aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>2000-04-21 00:11:43 +0000
committerRichard Henderson <rth@cygnus.com>2000-04-21 00:11:43 +0000
commite7ba28b26d16dab2782758c8e030fa3fa9d2de64 (patch)
tree1f140225f382cc93f24a95c1abc6f017c9c366ba
parente59215f456ee38286f56e3b067db4738c4416ffe (diff)
Merge from mainline
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/condexec-branch@33297 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog5
-rwxr-xr-xconfig.sub3
-rw-r--r--contrib/ChangeLog4
-rwxr-xr-xcontrib/gcc_update1
-rw-r--r--gcc/ChangeLog452
-rw-r--r--gcc/INSTALL485
-rw-r--r--gcc/Makefile.in64
-rw-r--r--gcc/aclocal.m453
-rw-r--r--gcc/basic-block.h1
-rw-r--r--gcc/bb-reorder.c19
-rw-r--r--gcc/builtins.c49
-rw-r--r--gcc/builtins.def1
-rw-r--r--gcc/c-common.c12
-rw-r--r--gcc/c-decl.c4
-rw-r--r--gcc/c-lex.c4
-rw-r--r--gcc/calls.c194
-rw-r--r--gcc/cccp.1674
-rw-r--r--gcc/cccp.c11310
-rw-r--r--gcc/cexp.c2206
-rw-r--r--gcc/cexp.y1223
-rw-r--r--gcc/ch/ChangeLog4
-rw-r--r--gcc/ch/decl.c4
-rw-r--r--gcc/ch/lex.c2
-rw-r--r--gcc/config.in9
-rw-r--r--gcc/config/avr/avr.c3
-rw-r--r--gcc/config/convex/convex.h1
-rw-r--r--gcc/config/fx80/fx80.h4
-rw-r--r--gcc/config/i370/i370.c2
-rw-r--r--gcc/config/i370/i370.h26
-rw-r--r--gcc/config/i370/i370.md63
-rw-r--r--gcc/config/i370/oe.h4
-rw-r--r--gcc/config/i370/xm-oe.h2
-rw-r--r--gcc/config/i386/i386.c46
-rw-r--r--gcc/config/i386/i386.h6
-rw-r--r--gcc/config/i386/i386.md233
-rw-r--r--gcc/config/i386/xm-os2.h1
-rw-r--r--gcc/config/i386/xm-sco.h8
-rw-r--r--gcc/config/ia64/sysv4.h4
-rw-r--r--gcc/config/m68k/m68k.h6
-rw-r--r--gcc/config/m68k/x-apollo684
-rw-r--r--gcc/config/m68k/x-ccur2
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c149
-rw-r--r--gcc/config/mips/mips.h147
-rw-r--r--gcc/config/mips/t-ecoff2
-rw-r--r--gcc/config/mips/t-elf2
-rw-r--r--gcc/config/mips/t-r39002
-rw-r--r--gcc/config/pdp11/pdp11.h5
-rw-r--r--gcc/config/romp/xm-romp.h5
-rw-r--r--gcc/config/sparc/sparc.c4
-rw-r--r--gcc/config/xm-linux.h3
-rwxr-xr-xgcc/configure821
-rw-r--r--gcc/configure.in32
-rw-r--r--gcc/conflict.c124
-rw-r--r--gcc/cp/ChangeLog87
-rw-r--r--gcc/cp/call.c5
-rw-r--r--gcc/cp/class.c233
-rw-r--r--gcc/cp/cp-tree.def6
-rw-r--r--gcc/cp/cp-tree.h26
-rw-r--r--gcc/cp/decl.c10
-rw-r--r--gcc/cp/decl2.c29
-rw-r--r--gcc/cp/inc/cxxabi.h3
-rw-r--r--gcc/cp/inc/typeinfo6
-rw-r--r--gcc/cp/lex.c2
-rw-r--r--gcc/cp/method.c62
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/rtti.c128
-rw-r--r--gcc/cp/tinfo2.cc5
-rw-r--r--gcc/cp/typeck.c6
-rw-r--r--gcc/cpperror.c1
-rw-r--r--gcc/cppexp.c16
-rw-r--r--gcc/cppfiles.c24
-rw-r--r--gcc/cpphash.c115
-rw-r--r--gcc/cpphash.h7
-rw-r--r--gcc/cppinit.c9
-rw-r--r--gcc/cpplex.c265
-rw-r--r--gcc/cpplib.c231
-rw-r--r--gcc/cpplib.h178
-rw-r--r--gcc/cse.c43
-rw-r--r--gcc/defaults.h2
-rw-r--r--gcc/dwarf2out.c75
-rw-r--r--gcc/emit-rtl.c3
-rw-r--r--gcc/expmed.c23
-rw-r--r--gcc/expr.h2
-rw-r--r--gcc/extend.texi35
-rw-r--r--gcc/f/ChangeLog7
-rw-r--r--gcc/f/g77install.texi2
-rw-r--r--gcc/f/lex.c2
-rw-r--r--gcc/f/version.c2
-rw-r--r--gcc/final.c3
-rw-r--r--gcc/fixinc/fixincl.c6
-rwxr-xr-xgcc/fixproto2
-rw-r--r--gcc/fold-const.c14
-rw-r--r--gcc/function.c7
-rw-r--r--gcc/gengenrtl.c2
-rw-r--r--gcc/ggc-common.c4
-rw-r--r--gcc/haifa-sched.c32
-rw-r--r--gcc/install.texi58
-rw-r--r--gcc/intl/loadmsgcat.c12
-rw-r--r--gcc/invoke.texi51
-rw-r--r--gcc/java/ChangeLog44
-rw-r--r--gcc/java/gjavah.c113
-rw-r--r--gcc/java/parse.c428
-rw-r--r--gcc/java/parse.y34
-rw-r--r--gcc/loop.c665
-rw-r--r--gcc/loop.h2
-rw-r--r--gcc/optabs.c1
-rw-r--r--gcc/po/ChangeLog5
-rw-r--r--gcc/po/POTFILES.in4
-rw-r--r--gcc/predict.c66
-rw-r--r--gcc/print-rtl.c76
-rw-r--r--gcc/print-tree.c6
-rw-r--r--gcc/protoize.c2
-rw-r--r--gcc/real.c13
-rw-r--r--gcc/reorg.c29
-rw-r--r--gcc/rtl.c8
-rw-r--r--gcc/rtl.h148
-rw-r--r--gcc/scan-decls.c22
-rw-r--r--gcc/simplify-rtx.c377
-rw-r--r--gcc/stmt.c30
-rw-r--r--gcc/stor-layout.c7
-rw-r--r--gcc/system.h20
-rw-r--r--gcc/testsuite/ChangeLog13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.abi/vtable2.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/catchptr1.C41
-rw-r--r--gcc/testsuite/g++.old-deja/g++.oliva/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb127.C2
-rw-r--r--gcc/testsuite/gcc.c-torture/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/921017-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp-mi.c22
-rw-r--r--gcc/toplev.c18
-rw-r--r--gcc/tree.c11
-rw-r--r--gcc/tree.h28
-rw-r--r--gcc/version.c2
-rw-r--r--include/ChangeLog10
-rw-r--r--include/hashtab.h15
-rw-r--r--include/symcat.h11
-rw-r--r--libf2c/libF77/Version.c2
-rw-r--r--libf2c/libI77/Version.c2
-rw-r--r--libf2c/libU77/Version.c2
-rw-r--r--libiberty/ChangeLog10
-rw-r--r--libiberty/cplus-dem.c8
-rw-r--r--libiberty/hashtab.c100
143 files changed, 4475 insertions, 18286 deletions
diff --git a/ChangeLog b/ChangeLog
index ba5e5188b38..92201f4d255 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2000-04-16 Dave Pitts <dpitts@cozx.com>
+
+ * config.sub (case $basic_machine): Change default for "ibm-*"
+ to "openedition".
+
2000-04-13 Andreas Jaeger <aj@suse.de>
* MAINTAINERS: Added myself.
diff --git a/config.sub b/config.sub
index 04eea53c319..0bb545d249c 100755
--- a/config.sub
+++ b/config.sub
@@ -1089,6 +1089,9 @@ case $basic_machine in
*-be)
os=-beos
;;
+ i370-*)
+ os=-openedition
+ ;;
*-ibm)
os=-aix
;;
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index e4423324e7c..4321ff25c31 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,7 @@
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * gcc_update: Remove references to cexp.c/cexp.y.
+
1999-12-18 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
* newcvsroot: Add check on the number of command-line arguments.
diff --git a/contrib/gcc_update b/contrib/gcc_update
index a25e275025b..67b00207f7e 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -67,7 +67,6 @@ gcc/c-parse.y: gcc/c-parse.in
gcc/c-parse.c: gcc/c-parse.y
gcc/c-parse.h: gcc/c-parse.c
gcc/c-gperf.h: gcc/c-parse.gperf
-gcc/cexp.c: gcc/cexp.y
gcc/fixinc/fixincl.x: gcc/fixinc/fixincl.tpl gcc/fixinc/inclhack.def
gcc/fixinc/inclhack.sh: gcc/fixinc/inclhack.def gcc/fixinc/inclhack.tpl gcc/fixinc/hackshell.tpl
gcc/fixinc/fixincl.sh: gcc/fixinc/inclhack.def gcc/fixinc/inclhack.tpl
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e08f5e86493..8488dd919be 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,395 @@
+2000-04-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpplib.h (enum cpp_ttype): Add token types for all
+ punctuators. Distinguish pp-numbers from valid C numbers.
+ Give some tokens better names. Initialize from macro.
+ (struct cpp_name, cpp_token, cpp_toklist): New data
+ structures.
+ Update prototypes.
+ * cpplex.c (bump_column, expand_name_space,
+ expand_token_space, init_token_list, cpp_output_list,
+ _cpp_scan_line): New functions.
+ (output_line_command): Add third argument, new line number.
+ * cpphash.h: Update prototypes.
+ * cppexp.c, cpphash.c, cpplib.c, scan-decls.c: Update for new
+ token names.
+
+2000-04-20 Richard Henderson <rth@cygnus.com>
+
+ * config/alpha/alpha.c (alpha_emit_floatuns): Emit missing barrier.
+
+2000-04-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * c-common.c (decl_attributes) [A_ALIAS]: Set TREE_USED on the
+ object pointed to.
+
+Thu Apr 20 14:19:18 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * loop.c (emit_iv_add_mult): Simplify it's input and emit
+ REG_EQUAL note explaining the calculated value.
+
+ * calls.c (expand_call): Avoid unnecesary precalculation
+ and outgoing parameters space guarding for sibling calls.
+ (store_one_arg): Likewise.
+
+Thu Apr 20 08:01:07 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * toplev.c (enum dump_file_index, dump_file): Add DFI_sibling.
+ (rest_of_compilation): Write sibling dump file and account
+ for time as jump time.
+ * invoke.texi: Update documentation on dump flags.
+
+2000-04-19 Marek Michalkiewicz <marekm@linux.org.pl>
+
+ * avr.c: #include "system.h" instead of <stdio.h> and <stdlib.h>.
+
+2000-04-19 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpphash.c (special_symbol): Represent an empty macro with
+ "\r \r " not just "\r ".
+ (_cpp_macroexpand): Correct condition for the foo ( ) special
+ case.
+ (unsafe_chars): Handle EOF as second argument.
+ (push_macro_expansion): Simplify test for removing escape at
+ end. Do not trim both escapes if there is no text in between.
+
+2000-04-19 Jim Blandy <jimb@redhat.com>
+
+ * dwarf2out.c (DWARF2_ADDR_SIZE): New macro. Use it instead
+ of PTR_SIZE, when appropriate.
+
+2000-04-19 Mark Mitchell <mark@codesourcery.com>
+
+ * system.h (ONLY_INT_FIELDS): Make sure it is defined.
+ (USE_ENUM_BITFIELDS): Fix typo.
+
+Wed Apr 19 12:14:55 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stor-layout.c (place_field): Set rli->offset_align properly.
+
+2000-04-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mips.h (BITS_PER_WORD, UNITS_PER_WORD, UNITS_PER_FPREG,
+ INT_TYPE_SIZE, LONG_TYPE_SIZE, POINTER_SIZE, POINTER_BOUNDARY,
+ PARM_BOUNDARY): Remove unnecessary casts.
+
+Wed Apr 19 12:02:37 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * calls.c (precompute_arguments): Remove must_preallocate and
+ args_size calls.
+ (expand_call): Update call of precompute_arguments.
+
+ * loop.c (check_insn_for_bivs, for_every_insn_in_loop,
+ check_insn_for_givs): Break out from ...
+ (strength_reduce) ... here; use for_every_insn_in_loop to call
+ check_insn_for_givs.
+ * loop.h (for_every_insn_in_loop): Declare.
+ (loop_insn_callback): New type.
+
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpplib.c (do_pragma_poison): Strings in the token buffer are
+ not nul-terminated.
+
+Tue Apr 18 16:04:12 2000 Jim Wilson <wilson@cygnus.com>
+
+ * config/ia64/sysv4.h (SELECT_SECTION): Use data_section if
+ flag_pic and RELOC.
+
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cccp.c, cexp.y, cexp.c, cccp.1: Removed.
+
+ * configure.in: Delete --disable-cpplib option and all
+ references to cpp_main.
+ * configure: Regenerate.
+ * Makefile.in: Remove all references to CCCP, CCCP_OBJS,
+ @cpp_main@, cccp.c, cexp.c, cexp.y, cexp.output, cexp.o,
+ cccp.o, cccp, or cppmain. Link cppmain.o straight to
+ cpp$(exeext). Add --no-headers to makeinfo command line when
+ generating INSTALL. Install and uninstall cpp.1 manpage, not
+ cccp.1.
+ * install.texi: Delete all references to cexp.y/cexp.c.
+ Delete ancient instructions for compiling GCC on 3b1.
+ * INSTALL: Regenerate.
+
+ * cppfiles.c, cpplib.h, jump.c, protoize.c, c-lex.c, mips/t-ecoff,
+ mips/t-elf, mips/t-r3900: Remove references to cccp.c.
+ * convex.h, fx80.h, m68k.h, pdp11.h: Remove references to
+ cexp.c/cexp.y.
+ * xm-linux.h, xm-os2.h, romp.h: Remove definition of BSTRING,
+ which is no longer tested anywhere.
+
+ * cppinit.c (handle_option): Don't run error message through
+ gettext twice.
+
+Tue Apr 18 14:16:47 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * conflict.c (conflict_graph_add): Pass enum type to htab_find_slot.
+ * cpperror.c (hashtab.h): Now include.
+ * cppexp.c (hashtab.h): Likewise.
+ * cpplex.c (hashtab.h): Likewise.
+ * cppfiles.c (hashtab.h): Likewise.
+ (find_include_file, _cpp_calc_hash, cpp_read_file): Pass enum type
+ to htab_find_slot_with_hash.
+ * cpphash.c (hashtab.h): Now include.
+ (_cpp_lookup_slot): INSERT is now enum insert_option.
+ * cpphash.h (_cpp_lookup_slot): Likewise.
+ * cppinit.c (hashtab.h): Include earlier.
+ (initialize_builtins): Pass enum to htab_find_slot.
+ * cpplib.c (hashtab.h): Now include.
+ (do_define, do_undef): Pass enum type to _cpp_lookup_slot.
+ (do_pragma_poison, do_assert): Likewise.
+ * emit-rtl.c (gen_rtx_CONST_INT): Pass enum to
+ htab_find_slot_with_hash.
+ * simplify-rtx.c (cselib_lookup_mem, cselib_lookup): Likewise.
+ * tree.c (type_hash_add): Likewise.
+ (build1): Minor cleanup.
+
+ * ggc-common.c: Add missing blanks.
+ * print-tree.c (print_node): Print DECL_OFFSET_ALIGN.
+ * tree.h (DECL_OFFSET_ALIGN): Fix typo in comment.
+
+ * stmt.c (mark_case_node): New function.
+ (mark_case_nesting): Call it.
+
+ * expmed.c (emit_store_flag): If comparing two-word integer
+ with zero, can optimize NE, EQ, GE, and LT.
+
+ * c-decl.c (mark_binding_level): Use 'for' instead of `while'.
+ * conflict.c: Minor cleanups.
+ * optabs.c: Add blank line
+ * simplify-rtx.c: Minor cleanups.
+
+2000-04-18 Stan Cox <scox@cygnus.com>
+
+ * gengenrtl.c (genlegend): Fix misspelling.
+
+2000-04-18 Robert Lipe <robertlipe@usa.net>
+
+ * configure.in (ENUM_BITFIELDS_ARE_UNSIGNED): Added. Check that
+ bitfields of the host compiler are not signed quantities.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * system.h (USE_ENUM_BITFIELDS): Added.
+ (ENUM_BITFIELDS): Added.
+ * rtl.h (rtx_def): Members `code', `mode', now ENUM_BITFIELD.
+ (SHORT_ENUM_BUG): Deleted.
+ * tree.h (tree_common): Members `code', `mode', `built_in_class',
+ now ENUM_BITFIELD.
+ * config/i386/xm-sco.h (ONLY_INT_FIELDS): Deleted.
+ (CODE_FIELD_BUG): Likewise.
+ * config/m68k/x-apollo68 (CC): Deleted SHORT_ENUM_BUG.
+ (OLD_CC): Likewise.
+ * config/m68k/x-ccur (X_CFLAGS): Likewise.
+
+2000-04-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cpplex.c (_cpp_lex_token): Don't call CPP_BUMP_LINE when the
+ mark is active.
+
+2000-04-17 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cppexp.c (lex): Don't assume tokens are NUL terminated.
+ * cpplib.c (do_include, do_import, do_include_next,
+ read_line_number, detect_if_not_defined): Likewise.
+ * cpphash.c (collect_expansion): Likewise.
+ (special_symbol, _cpp_macroexpand): Check return from
+ cpp_file_buffer.
+ * cpphash.h (CPP_NUL_TERMINATE, CPP_NUL_TERMINATE_Q): Delete
+ macros. Delete all uses.
+
+ * gcc.dg/cpp-mi.c: Add two more test cases.
+ * gcc.dg/cpp-mind.h, gcc.dg/cpp-mindp.h: New files.
+
+2000-04-17 Richard Henderson <rth@cygnus.com>
+
+ * bb-reorder.c (fixup_reorder_chain): Don't look up new block again.
+ (reorder_basic_blocks): If no epilogue in rtl, force last block last.
+
+2000-04-17 Mark Mitchell <mark@codesourcery.com>
+
+ * function.c (expand_function_start): Use hard_function_value to
+ compute the RTL to use for DECL_RESULT.
+
+Mon Apr 17 23:35:29 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (athlon_cost): Fix lea, divide and XFmode move costs.
+ (x86_integer_DFmode_moves, x86_partial_reg_dependency,
+ x86_memory_mismatch_stall): New global variables.
+ (ix86_adjust_cost): Handle MEMORY_BOTH on places MEMORY_STORE was only
+ alloved; fix load penalties for Athlon.
+ * i386.h (x86_integer_DFmode_moves, x86_partial_reg_dependency,
+ x86_memory_mismatch_stall): Declare.
+ (TARGET_INTEGER_DFMODE_MOVES, TARGET_PARTIAL_REG_DEPENDENCY,
+ TARGET_MEMORY_MISMATCH_STALL): New.
+ * i386.md (athlon scheduling parameters): Fix latencies according to
+ Athlon Optimization Manual.
+ (sahf, xchg, fldcw, leave instruction patterns): Set athlon_decode to
+ vector.
+ (fsqrt instruction patterns): Set athlon_decode to direct.
+ (movhi_1): Promote for TARGET_PARTIAL_REG_DEPENDENCY and for
+ PARTIAL_REGISTER_STALL with !TARGET_HIMODE_MATH machines.
+ (movqi_1): Handle promoting correctly for TARGET_PARTIAL_REG_DEPENDENCY
+ and TARGET_PARTIAL_REGISTER_STALL machines.
+ (pushdf_nointeger): New pattern.
+ (pushdf_integer): Rename from pushdf.
+ (movdf_nointger): Enable for !TARGET_INTEGER_DFMODE_MOVES machines.
+ (movdf_intger): Disable for !TARGET_INTEGER_DFMODE_MOVES machines.
+
+2000-04-17 Richard Henderson <rth@cygnus.com>
+
+ * loop.c (canonicalize_condition): Add WANT_REG argument.
+ Stop the search if we match it.
+ * expr.h (canonicalize_condition): Update decl.
+ * predict.c (expected_value_to_br_prob): Use it. Track last
+ expected value note.
+ (find_expected_value): Remove.
+
+ * reorg.c (mostly_true_jump): Always use BR_PROB if present.
+
+2000-04-17 Zack Weinberg <zack@wolery.cumb.org>
+
+ * aclocal.m4 (AM_GNU_GETTEXT): Don't AC_REQUIRE([AC_FUNC_MMAP]).
+ (AC_FUNC_MMAP_FILE): New macro, tests read-only private map of
+ a plain file.
+ * configure.in: Call AC_FUNC_MMAP_FILE.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+ * intl/loadmsgcat.c: Test HAVE_MMAP_FILE not HAVE_MMAP.
+ * fixinc/fixincl.c: Likewise.
+
+2000-04-17 Richard Henderson <rth@cygnus.com>
+
+ * builtins.c (expand_builtin_expect): New.
+ (expand_builtin): Call it.
+ * builtins.def (BUILT_IN_EXPECT): New.
+ * c-common.c (c_common_nodes_and_builtins): Declare __builtin_expect.
+ * extend.texi: Document it.
+
+ * predict.c (expected_value_to_br_prob): New.
+ (find_expected_value): New.
+ * basic-block.h (expected_value_to_br_prob): Declare.
+ * toplev.c (rest_of_compilation): Invoke it.
+
+ * rtl.h (NOTE_EXPECTED_VALUE): New.
+ (NOTE_INSN_EXPECTED_VALUE): New.
+ * rtl.c (note_insn_name): Update.
+ * print-rtl.c (print_rtx): Reorg NOTE_LINE_NUMBER special
+ cases; handle NOTE_INSN_EXPECTED_VALUE.
+
+2000-04-17 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/sparc.c (eligible_for_sibcall_delay): Cannot use
+ leaf sibcall delay slot if flag_pic.
+ (output_sibcall): Always emit call for leaf sibcall if flag_pic.
+
+2000-04-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (stmp-fixproto): Acknowledge errors in fixproto.
+
+ * fixproto: If fix-header fails, exit with an error.
+
+Mon Apr 17 14:59:36 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * cse.c (struct check_depdendence_data): New.
+ (check_dependence): New function.
+ (invalidate): Use check_depdenence.
+
+2000-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * dwarf2out.c (DWARF_CIE_DATA_ALIGNMENT): Adjust, now that
+ UNITS_PER_WORD is unsigned.
+
+ * tree.h (struct tree_common): Remove misleading comment.
+
+2000-04-16 Dave Pitts <dpitts@cozx.com>
+
+ * Makefile.in ($(srcdir)/c-parse.y: c-parse.in): Enclose the whole
+ message in quotes. Otherwise, IBM's make program treats the '#' as the
+ start of a comment and ignores the remainder of the line.
+
+ * c-lex.c (yylex): Change for EBCDIC, lower case characters preceed
+ upper case.
+ * cccp.c (initialize_char_syntax): Allow for holes in EBCDIC.
+ * cexp.y (initialize_random_junk): Likewise.
+ * cppfiles.c (find_include_file): Cast alloca return value.
+ * cppinit.c (initialize_standard_includes): Likewise.
+ * cpplib.c (cpp_define, cpp_undef): Likewise.
+ * defaults.h (ASM_OUTPUT_ASCII): Use ISPRINT.
+ * final.c (output_asm_insn): Allow for holes in EBCDIC.
+ * fold-const.c (CHARMASK): New.
+ (real_hex_to_f): Use it.
+ * real.c (CHARMASK): New.
+ (etoasc, asctoeg): Use it.
+ (asctoeg): EBCDIC lower case characters preceed upper case.
+
+ * i370.c (mvs_add_label): Change spacing for coding conventions.
+ * i370.h (ASM_OUTPUT_CASE_LABEL): Change to the data CSECT for the
+ outputing case vectors.
+ (ASM_OUTPUT_CASE_END): New, put assembler back into code CSECT.
+ (ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT): Remove page check,
+ since vector in in the data CSECT.
+ (ASM_OUTPUT_REG_POP, ASM_OUTPUT_REG_PUSH): Restore to correct operation.
+ * i370.md (Many patterns): Put the length in the XL directives.
+ (movdi): Put back STM and MVC in definition.
+ (floatsidf2): Correct TARGET_ELF_ABI pattern and add back the LE370
+ pattern using the TCA.
+ * oe.h (CPP_SPEC): Added to allow trigraphs.
+ * xm-oe.h (HOST_BITS_PER_LONGLONG): Change to 32. IBM's compiler does
+ not support the "long long" type.
+
+2000-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * config/mips/mips-protos.h (mips_legitimate_address_p): New
+ function.
+ (mips_reg_mode_ok_for_base_p): Likewise.
+ * config/mips/mips.h (REG_OK_STRICT_P): Don't define.
+ (REG_OK_FOR_INDEX_P): Define unconditionally.
+ (REG_MODE_OK_FOR_BASE_P): Use mips_reg_mode_ok_for_base_p.
+ (GO_IF_LEGITIMATE_ADDRESS): Use mips_legitimate_address_p.
+ * config/mips/mips.c (mips16_simple_memory_operand): Adjust now
+ that GET_MODE_SIZE is unsigned.
+ (mips_reg_mode_ok_for_base_p): Define.
+ (mips_legitimate_address_p): Likewise. Adjust now
+ that GET_MODE_SIZE is unsigned.
+ (block_move_loop): Make the number of bytes unsigned.
+ (expand_block_move): Likewise.
+ (function_arg): Make the loop counter unsigned to match the
+ boundary condition.
+
+2000-04-16 Richard Henderson <rth@cygnus.com>
+
+ * rtl.h (enum insn_note): New enumeration. Subsume
+ NOTE_INSN_DELETED and friends.
+ (GET_NOTE_INSN_NAME): Adjust index by NOTE_INSN_BIAS.
+ * rtl.c (note_insn_name): Tweak string order.
+
+2000-04-15 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpplex.c (_cpp_read_and_prescan): Enlarge len by setting it
+ to offset * 2.
+
+ * cpplex.c (output_line_command): Remove debugging prints.
+ (cpp_output_tokens): Don't write out a zero-length buffer or
+ try to see if it has a newline in it.
+ (_cpp_expand_to_buffer): Copy the source buffer before pushing.
+ (_cpp_read_and_prescan): Move shift-down of pushback bytes to
+ the end of the loop. Use memmove. Don't read past the end of
+ the buffer. Remove trailing newlines from error messages.
+
+2004-04-16 Neil Booth <NeilB@earthling.net>
+
+ * cpphash.h (SYNTAX_INCLUDE, SYNTAX_ASSERT, directive_handler): new.
+ * cpplib.c: Add new syntax flags to directive table, and
+ supporting macros.
+
+2000-04-15 Ulrich Drepper <drepper@redhat.com>
+
+ * i386.c (ix86_expand_epilogue): Yes, the x86 can pop 64k at once
+ using ret $N.
+
2000-04-15 David Edelsohn <edelsohn@gnu.org>
* toplev.c (display_help): Prefix "f" to "sched-verbose=".
@@ -175,8 +567,8 @@ Fri Apr 14 10:54:22 2000 Jim Wilson <wilson@cygnus.com>
2000-04-14 Richard Henderson <rth@cygnus.com>
- * fold-const.c (extract_muldiv): Don't distribute and widen
- multiply across plus for non-sizetype unsigned types.
+ * fold-const.c (extract_muldiv): Don't distribute and widen
+ multiply across plus for non-sizetype unsigned types.
2000-04-14 Richard Henderson <rth@cygnus.com>
@@ -204,7 +596,7 @@ Thu Apr 13 19:39:56 2000 Clinton Popetz <cpopetz@cygnus.com>
2000-04-13 Andreas Jaeger <aj@suse.de>
* config/mips/mips.c (expand_block_move): Pass alignment
- argument to move_by_pieces in bits, not bytes.
+ argument to move_by_pieces in bits, not bytes.
* config/mips/linux.h (CPP_PREDEFINES): Also define __PIC__ and
__pic__ for little endian.
@@ -307,8 +699,8 @@ Wed Apr 12 15:54:11 MET DST 2000 Jan Hubicka <jh@suse.cz>
Wed Apr 12 07:51:54 2000 Catherine Moore <clm@cygnus.com>
- * calls.c (emit_library_call_value_1): Change 3rd arg to
- locate_and_pad_parm to disregard the setting of partial.
+ * calls.c (emit_library_call_value_1): Change 3rd arg to
+ locate_and_pad_parm to disregard the setting of partial.
Wed Apr 12 08:47:38 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
@@ -1460,7 +1852,7 @@ Wed Apr 5 12:35:18 2000 Hans-Peter Nilsson <hp@axis.com>
all (op (minus A B) 0) with (op A B).
Wed Apr 5 18:03:31 2000 Toshiyasu Morita (toshi.morita@sega.com)
- J"orn Rennecke <amylaar@cygnus.co.uk>
+ J"orn Rennecke <amylaar@cygnus.co.uk>
* sh.md (block_lump_real_i4): Add missing clobber of T_REG
(block_lump_real): Likewise.
@@ -3839,11 +4231,11 @@ Thu Mar 16 02:14:16 2000 Hans-Peter Nilsson <hp@bitrange.com>
2000-01-27 Clinton Popetz <cpopetz@cygnus.com>
- * rs6000.c (rs6000_emit_load_toc_table): Use "LCG" and
- reload_toc_labelno for non-prologue TOC reloads. Also, don't
- increment rs6000_pic_labelno here.
- (rs6000_emit_prologue): Pass TRUE to rs6000_emit_load_toc_table,
- and increment rs6000_pic_labelno here.
+ * rs6000.c (rs6000_emit_load_toc_table): Use "LCG" and
+ reload_toc_labelno for non-prologue TOC reloads. Also, don't
+ increment rs6000_pic_labelno here.
+ (rs6000_emit_prologue): Pass TRUE to rs6000_emit_load_toc_table,
+ and increment rs6000_pic_labelno here.
2000-01-24 Geoffrey Keating <geoffk@cygnus.com>
@@ -4022,29 +4414,29 @@ Thu Mar 16 02:14:16 2000 Hans-Peter Nilsson <hp@bitrange.com>
2000-01-07 David Edelsohn <edelsohn@gnu.org>
- * rs6000.c (processor_target_table): Add power3 as alias for 630.
- * aix43.h: Revert Aug 2 change.
- (HAS_INIT_SECTION): Define, not visible yet.
- (LD_INIT_SWITCH): Define, not visible yet.
- * t-aix43 (MULTILIB_OPTIONS): Revert Aug 2 change.
+ * rs6000.c (processor_target_table): Add power3 as alias for 630.
+ * aix43.h: Revert Aug 2 change.
+ (HAS_INIT_SECTION): Define, not visible yet.
+ (LD_INIT_SWITCH): Define, not visible yet.
+ * t-aix43 (MULTILIB_OPTIONS): Revert Aug 2 change.
2000-01-04 Joel Sherrill (joel@OARcorp.com>
- * config/rs6000/rtems.h: Include config/rtems.h.
+ * config/rs6000/rtems.h: Include config/rtems.h.
2000-01-04 David Edelsohn <edelsohn@gnu.org>
- * rs6000.h (HANDLE_PRAGMA_PACK): Define.
- (SLOW_UNALIGNED_ACCESS): Define.
- (CASE_VECTOR_MODE): Always use 32-bit offsets.
- (ASM_FILE_END): Generate 64-bit symbol in 64-bit mode.
- (EXTRA_SECTOIN_FUNCTIONS): Indent .csect pseudo-op.
- (toc_section): Likewise and .toc pseudo-op.
- (ASM_DECLARE_FUNCTION): Likewise. Align text more strictly in
- 64-bit mode.
- (TEXT_SECTION_ASM_OP): Likewise.
- (ASM_OUTPUT_ADD_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT): Always use
- 32-bit offsets.
+ * rs6000.h (HANDLE_PRAGMA_PACK): Define.
+ (SLOW_UNALIGNED_ACCESS): Define.
+ (CASE_VECTOR_MODE): Always use 32-bit offsets.
+ (ASM_FILE_END): Generate 64-bit symbol in 64-bit mode.
+ (EXTRA_SECTOIN_FUNCTIONS): Indent .csect pseudo-op.
+ (toc_section): Likewise and .toc pseudo-op.
+ (ASM_DECLARE_FUNCTION): Likewise. Align text more strictly in
+ 64-bit mode.
+ (TEXT_SECTION_ASM_OP): Likewise.
+ (ASM_OUTPUT_ADD_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT): Always use
+ 32-bit offsets.
1999-12-17 Jakub Jelinek <jakub@redhat.com>
@@ -4061,7 +4453,7 @@ Thu Mar 16 02:14:16 2000 Hans-Peter Nilsson <hp@bitrange.com>
2000-01-05 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
- * rs6000.h: Continue cleanup.
+ * rs6000.h: Continue cleanup.
* aix.h: Likewise.
* lynx.h: Likewise.
* netware.h: Likewise.
@@ -16128,7 +16520,7 @@ Sat Oct 9 12:18:16 1999 Richard Henderson <rth@cygnus.com>
(count_or_remove_death_notes): New.
(verify_flow_info): Abort on error after all checks.
(remove_edge): Decrement n_edges.
- (remove_fake_edges): Tweek format.
+ (remove_fake_edges): Tweak format.
* haifa-sched.c (schedule_insns): Use split_all_insns.
* output.h (update_life_info): Remove declaration.
* recog.c (split_all_insns): From the corpse of split_block_insns,
diff --git a/gcc/INSTALL b/gcc/INSTALL
index a7c63d57de8..37fca13c68e 100644
--- a/gcc/INSTALL
+++ b/gcc/INSTALL
@@ -1,32 +1,16 @@
-This is Info file INSTALL, produced by Makeinfo version 1.68 from the
-input file install1.texi.
-
- This file documents the installation of the GNU compiler. Copyright
+This file documents the installation of the GNU compiler. Copyright
(C) 1988, 1989, 1992, 1994, 1995 Free Software Foundation, Inc. You
may copy, distribute, and modify it freely as long as you preserve this
copyright notice and permission notice.
-
-File: INSTALL, Node: Installation, Up: (dir)
-
Installing GNU CC
*****************
- Note most of this information is out of date and superceded by the
+ Note most of this information is out of date and superseded by the
EGCS install procedures. It is provided for historical reference only.
-* Menu:
-
-* Configurations:: Configurations Supported by GNU CC.
-* Other Dir:: Compiling in a separate directory (not where the source is).
-* Cross-Compiler:: Building and installing a cross-compiler.
-* Sun Install:: See below for installation on the Sun.
-* VMS Install:: See below for installation on VMS.
-* Collect2:: How `collect2' works; how it finds `ld'.
-* Header Dirs:: Understanding the standard header file directories.
-
- Here is the procedure for installing GNU CC on a Unix system. See
-*Note VMS Install::, for VMS systems. In this section we assume you
+ Here is the procedure for installing GNU CC on a GNU or Unix system.
+See *Note VMS Install::, for VMS systems. In this section we assume you
compile in the same directory that contains the source files; see *Note
Other Dir::, to find out how to compile in a separate directory on Unix
systems.
@@ -47,8 +31,26 @@ and includes all the necessary compilation tools and libraries.
`/usr/ucb' in `PATH'. The `cc' command in `/usr/ucb' uses
libraries which have bugs.
- 3. Specify the host, build and target machine configurations. You do
- this by running the file `configure'.
+ 3. Make sure the Bison parser generator is installed. (This is
+ unnecessary if the Bison output file `c-parse.c' is more recent
+ than `c-parse.y',and you do not plan to change the `.y' file.)
+
+ Bison versions older than Sept 8, 1988 will produce incorrect
+ output for `c-parse.c'.
+
+ 4. If you have chosen a configuration for GNU CC which requires other
+ GNU tools (such as GAS or the GNU linker) instead of the standard
+ system tools, install the required tools in the build directory
+ under the names `as', `ld' or whatever is appropriate. This will
+ enable the compiler to find the proper tools for compilation of
+ the program `enquire'.
+
+ Alternatively, you can do subsequent compilation using a value of
+ the `PATH' environment variable such that the necessary GNU tools
+ come before the standard system tools.
+
+ 5. Specify the host, build and target machine configurations. You do
+ this when you run the `configure' script.
The "build" machine is the system which you are using, the "host"
machine is the system where you want to run the resulting compiler
@@ -97,9 +99,10 @@ and includes all the necessary compilation tools and libraries.
the notes in that section before proceeding any further with the
installation of GNU CC.
- There are four additional options you can specify independently to
- describe variant hardware and software configurations. These are
- `--with-gnu-as', `--with-gnu-ld', `--with-stabs' and `--nfp'.
+ 6. When running `configure', you may also need to specify certain
+ additional options that describe variant hardware and software
+ configurations. These are `--with-gnu-as', `--with-gnu-ld',
+ `--with-stabs' and `--nfp'.
`--with-gnu-as'
If you will use GNU CC with the GNU assembler (GAS), you
@@ -205,104 +208,130 @@ and includes all the necessary compilation tools and libraries.
the compiler and may only work properly if you are building
the compiler with GNU C.
- The `configure' script searches subdirectories of the source
- directory for other compilers that are to be integrated into GNU
- CC. The GNU compiler for C++, called G++ is in a subdirectory
- named `cp'. `configure' inserts rules into `Makefile' to build
- all of those compilers.
-
- Here we spell out what files will be set up by `configure'.
- Normally you need not be concerned with these files.
-
- * A file named `config.h' is created that contains a `#include'
- of the top-level config file for the machine you will run the
- compiler on (*note The Configuration File:
- (gcc.info)Config.). This file is responsible for defining
- information about the host machine. It includes `tm.h'.
-
- The top-level config file is located in the subdirectory
- `config'. Its name is always `xm-SOMETHING.h'; usually
- `xm-MACHINE.h', but there are some exceptions.
-
- If your system does not support symbolic links, you might
- want to set up `config.h' to contain a `#include' command
- which refers to the appropriate file.
-
- * A file named `tconfig.h' is created which includes the
- top-level config file for your target machine. This is used
- for compiling certain programs to run on that machine.
-
- * A file named `tm.h' is created which includes the
- machine-description macro file for your target machine. It
- should be in the subdirectory `config' and its name is often
- `MACHINE.h'.
-
- * The command file `configure' also constructs the file
- `Makefile' by adding some text to the template file
- `Makefile.in'. The additional text comes from files in the
- `config' directory, named `t-TARGET' and `x-HOST'. If these
- files do not exist, it means nothing needs to be added for a
- given target or host.
-
- 4. The standard directory for installing GNU CC is `/usr/local/lib'.
- If you want to install its files somewhere else, specify
- `--prefix=DIR' when you run `configure'. Here DIR is a directory
- name to use instead of `/usr/local' for all purposes with one
- exception: the directory `/usr/local/include' is searched for
- header files no matter where you install the compiler. To override
- this name, use the `--with-local-prefix' option below. The
- directory you specify need not exist, but its parent directory
- must exist.
-
- 5. Specify `--with-local-prefix=DIR' if you want the compiler to
- search directory `DIR/include' for locally installed header files
- *instead* of `/usr/local/include'.
-
- You should specify `--with-local-prefix' *only* if your site has a
- different convention (not `/usr/local') for where to put
- site-specific files.
-
- The default value for `--with-local-prefix' is `/usr/local'
- regardless of the value of `--prefix'. Specifying `--prefix' has
- no effect on which directory GNU CC searches for local header
- files. This may seem counterintuitive, but actually it is logical.
-
- The purpose of `--prefix' is to specify where to *install GNU CC*.
- The local header files in `/usr/local/include'--if you put any in
- that directory--are not part of GNU CC. They are part of other
- programs--perhaps many others. (GNU CC installs its own header
- files in another directory which is based on the `--prefix' value.)
-
- *Do not* specify `/usr' as the `--with-local-prefix'! The
- directory you use for `--with-local-prefix' *must not* contain any
- of the system's standard header files. If it did contain them,
- certain programs would be miscompiled (including GNU Emacs, on
- certain targets), because this would override and nullify the
- header file corrections made by the `fixincludes' script.
-
- Indications are that people who use this option use it based on
- mistaken ideas of what it is for. People use it as if it specified
- where to install part of GNU CC. Perhaps they make this assumption
- because installing GNU CC creates the directory.
-
- 6. Make sure the Bison parser generator is installed. (This is
- unnecessary if the Bison output files `c-parse.c' and `cexp.c' are
- more recent than `c-parse.y' and `cexp.y' and you do not plan to
- change the `.y' files.)
-
- Bison versions older than Sept 8, 1988 will produce incorrect
- output for `c-parse.c'.
-
- 7. If you have chosen a configuration for GNU CC which requires other
- GNU tools (such as GAS or the GNU linker) instead of the standard
- system tools, install the required tools in the build directory
- under the names `as', `ld' or whatever is appropriate. This will
- enable the compiler to find the proper tools for compilation of
- the program `enquire'.
-
- Alternatively, you can do subsequent compilation using a value of
- the `PATH' environment variable such that the necessary GNU tools
- come before the standard system tools.
+ The `configure' script searches subdirectories of the source
+ directory for other compilers that are to be integrated into
+ GNU CC. The GNU compiler for C++, called G++ is in a
+ subdirectory named `cp'. `configure' inserts rules into
+ `Makefile' to build all of those compilers.
+
+ Here we spell out what files will be set up by `configure'.
+ Normally you need not be concerned with these files.
+
+ * A file named `config.h' is created that contains a
+ `#include' of the top-level config file for the machine
+ you will run the compiler on (*note The Configuration
+ File: (gcc.info)Config.). This file is responsible for
+ defining information about the host machine. It
+ includes `tm.h'.
+
+ The top-level config file is located in the subdirectory
+ `config'. Its name is always `xm-SOMETHING.h'; usually
+ `xm-MACHINE.h', but there are some exceptions.
+
+ If your system does not support symbolic links, you
+ might want to set up `config.h' to contain a `#include'
+ command which refers to the appropriate file.
+
+ * A file named `tconfig.h' is created which includes the
+ top-level config file for your target machine. This is
+ used for compiling certain programs to run on that
+ machine.
+
+ * A file named `tm.h' is created which includes the
+ machine-description macro file for your target machine.
+ It should be in the subdirectory `config' and its name
+ is often `MACHINE.h'.
+
+ `--enable-nls'
+ `--disable-nls'
+ The `--enable-nls' option enables Native Language Support
+ (NLS), which lets GCC output diagnostics in languages other
+ than American English. No translations are available yet, so
+ the main users of this option now are those translating GCC's
+ diagnostics who want to test their work. Once translations
+ become available, Native Language Support will become enabled
+ by default. The `--disable-nls' option disables NLS.
+
+ `--with-included-gettext'
+ If NLS is enabled, the GCC build procedure normally attempts
+ to use the host's `gettext' libraries, and falls back on
+ GCC's copy of the GNU `gettext' library only if the host
+ libraries do not suffice. The `--with-included-gettext'
+ option causes the build procedure to prefer its copy of GNU
+ `gettext'.
+
+ `--with-catgets'
+ If NLS is enabled, and if the host lacks `gettext' but has the
+ inferior `catgets' interface, the GCC build procedure normally
+ ignores `catgets' and instead uses GCC's copy of the GNU
+ `gettext' library. The `--with-catgets' option causes the
+ build procedure to use the host's `catgets' in this situation.
+
+ `--enable-win32-registry'
+ `--enable-win32-registry=KEY'
+ `--disable-win32-registry'
+ The `--enable-win32-registry' option enables Windows-hosted
+ GCC to look up installations paths in the registry using the
+ following key:
+
+ `HKEY_LOCAL_MACHINE\SOFTWARE\Free Software Foundation\<KEY>'
+
+ <KEY> defaults to GCC version number, and can be overridden
+ by the `--enable-win32-registry=KEY' option. Vendors and
+ distributors who use custom installers are encouraged to
+ provide a different key, perhaps one comprised of vendor name
+ and GCC version number, to avoid conflict with existing
+ installations. This feature is enabled by default, and can be
+ disabled by `--disable-win32-registry' option. This option
+ has no effect on the other hosts.
+
+ 7. In certain cases, you should specify certain other options when
+ you run `configure'.
+
+ * The standard directory for installing GNU CC is
+ `/usr/local/lib'. If you want to install its files somewhere
+ else, specify `--prefix=DIR' when you run `configure'. Here
+ DIR is a directory name to use instead of `/usr/local' for
+ all purposes with one exception: the directory
+ `/usr/local/include' is searched for header files no matter
+ where you install the compiler. To override this name, use
+ the `--with-local-prefix' option below. The directory you
+ specify need not exist, but its parent directory must exist.
+
+ * Specify `--with-local-prefix=DIR' if you want the compiler to
+ search directory `DIR/include' for locally installed header
+ files *instead* of `/usr/local/include'.
+
+ You should specify `--with-local-prefix' *only* if your site
+ has a different convention (not `/usr/local') for where to put
+ site-specific files.
+
+ The default value for `--with-local-prefix' is `/usr/local'
+ regardless of the value of `--prefix'. Specifying `--prefix'
+ has no effect on which directory GNU CC searches for local
+ header files. This may seem counterintuitive, but actually
+ it is logical.
+
+ The purpose of `--prefix' is to specify where to *install GNU
+ CC*. The local header files in `/usr/local/include'--if you
+ put any in that directory--are not part of GNU CC. They are
+ part of other programs--perhaps many others. (GNU CC
+ installs its own header files in another directory which is
+ based on the `--prefix' value.)
+
+ *Do not* specify `/usr' as the `--with-local-prefix'! The
+ directory you use for `--with-local-prefix' *must not* contain
+ any of the system's standard header files. If it did contain
+ them, certain programs would be miscompiled (including GNU
+ Emacs, on certain targets), because this would override and
+ nullify the header file corrections made by the `fixincludes'
+ script.
+
+ Indications are that people who use this option use it based
+ on mistaken ideas of what it is for. People use it as if it
+ specified where to install part of GNU CC. Perhaps they make
+ this assumption because installing GNU CC creates the
+ directory.
8. Build the compiler. Just type `make LANGUAGES=c' in the compiler
directory.
@@ -325,17 +354,16 @@ and includes all the necessary compilation tools and libraries.
escape sequence" are normal in `genopinit.c' and perhaps some
other files. Likewise, you should ignore warnings about "constant
is so large that it is unsigned" in `insn-emit.c' and
- `insn-recog.c', a warning about a comparison always being zero in
- `enquire.o', and warnings about shift counts exceeding type widths
- in `cexp.y'. Any other compilation errors may represent bugs in
+ `insn-recog.c', and a warning about a comparison always being zero
+ in `enquire.o'. Any other compilation errors may represent bugs in
the port to your machine or operating system, and should be
investigated and reported.
- Some commercial compilers fail to compile GNU CC because they have
- bugs or limitations. For example, the Microsoft compiler is said
- to run out of macro space. Some Ultrix compilers run out of
- expression space; then you need to break up the statement where
- the problem happens.
+ Some compilers fail to compile GNU CC because they have bugs or
+ limitations. For example, the Microsoft compiler is said to run
+ out of macro space. Some Ultrix compilers run out of expression
+ space; then you need to break up the statement where the problem
+ happens.
9. If you are building a cross-compiler, stop here. *Note
Cross-Compiler::.
@@ -411,8 +439,8 @@ and includes all the necessary compilation tools and libraries.
instead of making `stage1', `stage2', and performing the two
compiler builds.
- 14. Then compare the latest object files with the stage 2 object
- files--they ought to be identical, aside from time stamps (if any).
+ 14. Compare the latest object files with the stage 2 object files--they
+ ought to be identical, aside from time stamps (if any).
On some systems, meaningful comparison of object files is
impossible; they always appear "different." This is currently
@@ -485,11 +513,9 @@ and includes all the necessary compilation tools and libraries.
or 3, since they usually run faster than the ones compiled with
some other compiler.)
- 16. If you're going to use C++, it's likely that you need to also
- install a C++ runtime library. Just as GNU C does not distribute
- a C runtime library, it also does not include a C++ runtime
- library. All I/O functionality, special class libraries, etc., are
- provided by the C++ runtime library.
+ 16. If you're going to use C++, you need to install the C++ runtime
+ library. This includes all I/O functionality, special class
+ libraries, etc.
The standard C++ runtime library for GNU CC is called `libstdc++'.
An obsolescent library `libg++' may also be available, but it's
@@ -566,19 +592,50 @@ and includes all the necessary compilation tools and libraries.
* thr-win32 Microsoft Win32 API thread support.
-
-File: INSTALL, Node: Configurations, Next: Other Dir, Up: Installation
+Files Created by `configure'
+============================
+
+ Here we spell out what files will be set up by `configure'. Normally
+you need not be concerned with these files.
+
+ * A file named `config.h' is created that contains a `#include' of
+ the top-level config file for the machine you will run the compiler
+ on (*note The Configuration File: (gcc.info)Config.). This file
+ is responsible for defining information about the host machine.
+ It includes `tm.h'.
+
+ The top-level config file is located in the subdirectory `config'.
+ Its name is always `xm-SOMETHING.h'; usually `xm-MACHINE.h', but
+ there are some exceptions.
+
+ If your system does not support symbolic links, you might want to
+ set up `config.h' to contain a `#include' command which refers to
+ the appropriate file.
+
+ * A file named `tconfig.h' is created which includes the top-level
+ config file for your target machine. This is used for compiling
+ certain programs to run on that machine.
+
+ * A file named `tm.h' is created which includes the
+ machine-description macro file for your target machine. It should
+ be in the subdirectory `config' and its name is often `MACHINE.h'.
+
+ * The command file `configure' also constructs the file `Makefile'
+ by adding some text to the template file `Makefile.in'. The
+ additional text comes from files in the `config' directory, named
+ `t-TARGET' and `x-HOST'. If these files do not exist, it means
+ nothing needs to be added for a given target or host.
Configurations Supported by GNU CC
==================================
Here are the possible CPU types:
- 1750a, a29k, alpha, arm, cN, clipper, dsp16xx, elxsi, h8300,
- hppa1.0, hppa1.1, i370, i386, i486, i586, i860, i960, m32r,
- m68000, m68k, m88k, mips, mipsel, mips64, mips64el, ns32k,
- powerpc, powerpcle, pyramid, romp, rs6000, sh, sparc, sparclite,
- sparc64, vax, we32k.
+ 1750a, a29k, alpha, arm, avr, cN, clipper, dsp16xx, elxsi, fr30,
+ h8300, hppa1.0, hppa1.1, i370, i386, i486, i586, i686, i786, i860,
+ i960, m32r, m68000, m68k, m88k, mcore, mips, mipsel, mips64,
+ mips64el, mn10200, mn10300, ns32k, pdp11, powerpc, powerpcle,
+ romp, rs6000, sh, sparc, sparclite, sparc64, v850, vax, we32k.
Here are the recognized company names. As you can see, customary
abbreviations are used rather than the longer official names.
@@ -744,12 +801,24 @@ special things you must know:
You may need to make a variant of the file `arm.h' for your
particular configuration.
-`arm-*-linuxaout'
- Any of the ARM family processors running the Linux-based GNU
- system with the `a.out' binary format (ELF is not yet supported).
- You must use version 2.8.1.0.7 or later of the GNU/Linux binutils,
- which you can download from `sunsite.unc.edu:/pub/Linux/GCC' and
- other mirror sites for Linux-based GNU systems.
+`arm-*-elf'
+ This configuration is intended for embedded systems.
+
+`arm-*-linux-gnuaout'
+ Any of the ARM-family processors running the Linux-based GNU
+ system with the `a.out' binary format. This is an obsolete
+ configuration.
+
+`arm-*-linux-gnu'
+`arm-*-linux-gnuoldld'
+ Any of the ARM-family processors running the Linux-based GNU
+ system with the `ELF' binary format. You must use version
+ 2.9.1.0.22 or later of the GNU/Linux binutils, which you can
+ download from `ftp.varesearch.com:/pub/support/hjl/binutils'.
+
+ These two configurations differ only in the required version of GNU
+ binutils. For binutils 2.9.1.0.x, use `arm-*-linux-gnuoldld'. For
+ newer versions of binutils, use `arm-*-linux-gnu'.
`arm-*-riscix'
The ARM2 or ARM3 processor running RISC iX, Acorn's port of BSD
@@ -775,6 +844,12 @@ special things you must know:
`a29k-*-bsd'
AMD Am29050 used in a system running a variant of BSD Unix.
+`avr'
+ ATMEL AVR-family micro controllers. These are used in embedded
+ applications. There are no standard Unix configurations.
+ Supports following MCU's: - AT90S23xx - ATtiny22 - AT90S44xx -
+ AT90S85xx - ATmega603/603L - ATmega103/103L
+
`decstation-*'
MIPS-based DECstations can support three different personalities:
Ultrix, DEC OSF/1, and OSF/rose. (Alpha-based DECstation products
@@ -1019,37 +1094,11 @@ special things you must know:
the original.
`m68k-att-sysv'
- AT&T 3b1, a.k.a. 7300 PC. Special procedures are needed to
- compile GNU CC with this machine's standard C compiler, due to
- bugs in that compiler. You can bootstrap it more easily with
- previous versions of GNU CC if you have them.
-
- Installing GNU CC on the 3b1 is difficult if you do not already
- have GNU CC running, due to bugs in the installed C compiler.
- However, the following procedure might work. We are unable to
- test it.
-
- 1. Comment out the `#include "config.h"' line near the start of
- `cccp.c' and do `make cpp'. This makes a preliminary version
- of GNU cpp.
-
- 2. Save the old `/lib/cpp' and copy the preliminary GNU cpp to
- that file name.
-
- 3. Undo your change in `cccp.c', or reinstall the original
- version, and do `make cpp' again.
-
- 4. Copy this final version of GNU cpp into `/lib/cpp'.
-
- 5. Replace every occurrence of `obstack_free' in the file
- `tree.c' with `_obstack_free'.
-
- 6. Run `make' to get the first-stage GNU CC.
-
- 7. Reinstall the original version of `/lib/cpp'.
-
- 8. Now you can compile GNU CC with itself and install it in the
- normal fashion.
+ AT&T 3b1, a.k.a. 7300 PC. This version of GNU CC cannot be
+ compiled with the system C compiler, which is too buggy. You will
+ need to get a previous version of GCC and use it to bootstrap.
+ Binaries are available from the OSU-CIS archive, at
+ `ftp://archive.cis.ohio-state.edu/pub/att7300/'.
`m68k-bull-sysv'
Bull DPX/2 series 200 and 300 with BOS-2.00.45 up to BOS-2.01. GNU
@@ -1446,9 +1495,6 @@ special things you must know:
You may need to raise the ULIMIT setting to build a C++ compiler,
as the file `cc1plus' is larger than one megabyte.
-
-File: INSTALL, Node: Other Dir, Next: Cross-Compiler, Prev: Configurations, Up: Installation
-
Compilation in a Separate Directory
===================================
@@ -1493,9 +1539,6 @@ configuration steps shown above, when ordinary source files change. You
must, however, run `configure' again when the configuration files
change, if your system does not support symbolic links.
-
-File: INSTALL, Node: Cross-Compiler, Next: Sun Install, Prev: Other Dir, Up: Installation
-
Building and Installing a Cross-Compiler
========================================
@@ -1522,20 +1565,6 @@ If you want to link on other than the target machine, you need a
cross-linker as well. You also need header files and libraries suitable
for the target machine that you can install on the host machine.
-* Menu:
-
-* Steps of Cross:: Using a cross-compiler involves several steps
- that may be carried out on different machines.
-* Configure Cross:: Configuring a cross-compiler.
-* Tools and Libraries:: Where to put the linker and assembler, and the C library.
-* Cross Headers:: Finding and installing header files
- for a cross-compiler.
-* Cross Runtime:: Supplying arithmetic runtime routines (`libgcc1.a').
-* Build Cross:: Actually compiling the cross-compiler.
-
-
-File: INSTALL, Node: Steps of Cross, Next: Configure Cross, Up: Cross-Compiler
-
Steps of Cross-Compilation
--------------------------
@@ -1561,9 +1590,6 @@ machine, since then you can do it all with a single invocation of GNU
CC. This requires a suitable cross-assembler and cross-linker. For
some targets, the GNU assembler and linker are available.
-
-File: INSTALL, Node: Configure Cross, Next: Tools and Libraries, Prev: Steps of Cross, Up: Cross-Compiler
-
Configuring a Cross-Compiler
----------------------------
@@ -1576,9 +1602,6 @@ system running BSD on a system that `configure' can correctly identify:
./configure --target=m68k-hp-bsd4.3
-
-File: INSTALL, Node: Tools and Libraries, Next: Cross Headers, Prev: Configure Cross, Up: Cross-Compiler
-
Tools and Libraries for a Cross-Compiler
----------------------------------------
@@ -1647,9 +1670,6 @@ machine:
mget *crt*.o
quit
-
-File: INSTALL, Node: Cross Runtime, Next: Build Cross, Prev: Cross Headers, Up: Cross-Compiler
-
`libgcc.a' and Cross-Compilers
------------------------------
@@ -1735,9 +1755,6 @@ Otherwise, you should place your replacement library under the name
`libgcc1.a' in the directory in which you will build the
cross-compiler, before you run `make'.
-
-File: INSTALL, Node: Cross Headers, Next: Cross Runtime, Prev: Tools and Libraries, Up: Cross-Compiler
-
Cross-Compilers and Header Files
--------------------------------
@@ -1786,9 +1803,6 @@ machine. On the target machine, do this:
quit
tar xf tarfile
-
-File: INSTALL, Node: Build Cross, Prev: Cross Runtime, Up: Cross-Compiler
-
Actually Building the Cross-Compiler
------------------------------------
@@ -1822,9 +1836,6 @@ must specify a 68030 as the host when you configure it.
To install the cross-compiler, use `make install', as usual.
-
-File: INSTALL, Node: Sun Install, Next: VMS Install, Prev: Cross-Compiler, Up: Installation
-
Installing GNU CC on the Sun
============================
@@ -1860,9 +1871,6 @@ error which does not recur if you run it again. To fix the problem,
install Sun recommended patch 100726 (for SunOS 4.1.3) or 101508 (for
SunOS 4.1.3_U1), or upgrade to a later SunOS release.
-
-File: INSTALL, Node: VMS Install, Next: Collect2, Prev: Sun Install, Up: Installation
-
Installing GNU CC on VMS
========================
@@ -2068,9 +2076,6 @@ edit the file `tm.h' (created by `vmsconfig.com') to define the macro
`QSORT_WORKAROUND' is always defined when GNU CC is compiled with
VAX C, to avoid a problem in case `gcclib.olb' is not yet available.
-
-File: INSTALL, Node: Collect2, Next: Header Dirs, Prev: VMS Install, Up: Installation
-
`collect2'
==========
@@ -2136,9 +2141,6 @@ search path.
`collect2' searches for the utilities `nm' and `strip' using the
same algorithm as above for `ld'.
-
-File: INSTALL, Node: Header Dirs, Prev: Collect2, Up: Installation
-
Standard Header File Directories
================================
@@ -2150,9 +2152,9 @@ cross compilation header files need to be fixed, they must be installed
before GNU CC is built. If the cross compilation header files are
already suitable for ANSI C and GNU CC, nothing special need be done).
- `GPLUS_INCLUDE_DIR' means the same thing for native and cross. It
-is where `g++' looks first for header files. The C++ library installs
-only target independent header files in that directory.
+ `GPLUSPLUS_INCLUDE_DIR' means the same thing for native and cross.
+It is where `g++' looks first for header files. The C++ library
+installs only target independent header files in that directory.
`LOCAL_INCLUDE_DIR' is used only for a native compiler. It is
normally `/usr/local/include'. GNU CC searches this directory so that
@@ -2167,22 +2169,3 @@ use. For a cross-compiler, this is the equivalent of `/usr/include'.
When you build a cross-compiler, `fixincludes' processes any header
files in this directory.
-
-
-Tag Table:
-Node: Installation351
-Node: Configurations26618
-Node: Other Dir65739
-Node: Cross-Compiler67454
-Node: Steps of Cross69284
-Node: Configure Cross70401
-Node: Tools and Libraries71037
-Node: Cross Runtime73475
-Node: Cross Headers77555
-Node: Build Cross79553
-Node: Sun Install81428
-Node: VMS Install83099
-Node: Collect293028
-Node: Header Dirs95592
-
-End Tag Table
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f6e22a8ba10..4d73e7074fb 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -692,8 +692,6 @@ OBJS = diagnostic.o \
GEN= genemit genoutput genrecog genextract genflags gencodes genconfig \
genpeep gengenrtl gencheck
-CCCP=@cpp_main@
-
# Files to be copied away after each stage in building.
STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
@@ -707,9 +705,8 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
genattr$(build_exeext) genopinit$(build_exeext) gengenrtl$(build_exeext) \
gencheck$(build_exeext) \
xgcc$(exeext) xcpp$(exeext) cc1$(exeext) cpp$(exeext) $(EXTRA_PASSES) \
- $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) \
- $(CCCP)$(exeext) cc1obj$(exeext) enquire$(exeext) \
- protoize$(exeext) unprotoize$(exeext) \
+ $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) cc1obj$(exeext) \
+ enquire$(exeext) protoize$(exeext) unprotoize$(exeext) \
specs collect2$(exeext) $(USE_COLLECT2) underscore.c \
gcov$(exeext) *.[0-9][0-9].* *.[si] libcpp.a \
$(LANG_STAGESTUFF)
@@ -1360,7 +1357,7 @@ $(srcdir)/c-parse.y: c-parse.in
$(srcdir)/c-gperf.h: c-parse.gperf
gperf -L C -F ', 0, 0' -p -j1 -i 1 -g -o -t -G -N is_reserved_word \
-k1,3,$$ $(srcdir)/c-parse.gperf >tmp-gperf.h || ( \
- echo "See " $(website)/cvs.html#generated_files >&2 ; \
+ echo "See $(website)/cvs.html#generated_files" >&2 ; \
exit 1 )
$(SHELL) $(srcdir)/move-if-change tmp-gperf.h $(srcdir)/c-gperf.h
@@ -2014,7 +2011,7 @@ $(top_builddir)/intl/libintl.a:
# Make sure all the headers are there for xgettext to scan.
$(INTL_TARGETS): $(srcdir)/c-gperf.h \
- $(srcdir)/c-parse.c $(srcdir)/c-parse.h $(srcdir)/cexp.c
+ $(srcdir)/c-parse.c $(srcdir)/c-parse.h
intl.all intl.install intl.uninstall intl.distdir \
intl.mostlyclean intl.clean intl.distclean intl.maintainer-clean:
@@ -2033,37 +2030,18 @@ intl.distdir-fixup:
#
# Remake cpp and protoize.
-# Making the preprocessor
-cpp$(exeext): $(CCCP)$(exeext)
- -rm -f cpp$(exeext)
- $(LN) $(CCCP)$(exeext) cpp$(exeext)
-CCCP_OBJS = cccp.o cexp.o intl.o prefix.o version.o @extra_cpp_objs@ mbchar.o
-cccp$(exeext): $(CCCP_OBJS) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(CCCP_OBJS) $(LIBS)
-cexp.o: $(srcdir)/cexp.c $(CONFIG_H) system.h mbchar.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $(srcdir)/cexp.c
-$(srcdir)/cexp.c: $(srcdir)/cexp.y
- cd $(srcdir); $(BISON) -o cexp.c cexp.y
-
PREPROCESSOR_DEFINES = \
-DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
-DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
-DLOCAL_INCLUDE_DIR=\"$(includedir)\" \
-DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \
-DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\"
-# We use $(libsubdir)/$(unlibsubdir) to match the
-# -iprefix argument which gcc will pass if GCC_EXEC_PREFIX is used.
-cccp.o: cccp.c $(CONFIG_H) intl.h pcp.h version.c config.status system.h \
- mbchar.h prefix.h Makefile.in version.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- $(PREPROCESSOR_DEFINES) \
- -c `echo $(srcdir)/cccp.c | sed 's,^\./,,'`
LIBCPP_OBJS = cpplib.o cpphash.o cpperror.o cppexp.o cppfiles.o \
cppinit.o cppulp.o cpplex.o mkdeps.o \
prefix.o version.o mbchar.o @extra_cpp_objs@
-LIBCPP_DEPS = cpplib.h cpphash.h intl.h system.h
+LIBCPP_DEPS = cpplib.h cpphash.h intl.h system.h
# All the other archives built/used by this makefile are for targets. This
# one is strictly for the host.
@@ -2073,8 +2051,8 @@ libcpp.a: $(LIBCPP_OBJS)
$(AR) $(AR_FLAGS) libcpp.a $(LIBCPP_OBJS)
if $(RANLIB_TEST) ; then $(RANLIB) libcpp.a ; else true ; fi
-cppmain$(exeext): cppmain.o intl.o libcpp.a $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cppmain$(exeext) cppmain.o \
+cpp$(exeext): cppmain.o intl.o libcpp.a $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cpp$(exeext) cppmain.o \
intl.o libcpp.a $(LIBS)
cppmain.o: cppmain.c $(CONFIG_H) cpplib.h intl.h system.h
@@ -2317,7 +2295,7 @@ fixhdr.ready: fix-header
# if it has already been run on the files in `include'.
stmp-fixproto: fixhdr.ready fixproto stmp-int-hdrs
@echo "Various warnings and error messages from fixproto are normal"
- -if [ -f include/fixed ] ; then true; \
+ if [ -f include/fixed ] ; then true; \
else \
: This line works around a 'make' bug in BSDI 1.1.; \
FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"; export FIXPROTO_DEFINES; \
@@ -2325,6 +2303,7 @@ stmp-fixproto: fixhdr.ready fixproto stmp-int-hdrs
export mkinstalldirs; \
if [ -d $(SYSTEM_HEADER_DIR) ] ; then \
$(SHELL) ${srcdir}/fixproto include include $(SYSTEM_HEADER_DIR); \
+ if [ $$? -eq 0 ] ; then true ; else exit 1 ; fi ; \
else true; fi; \
touch include/fixed; \
fi
@@ -2361,7 +2340,7 @@ cpp.dvi: $(srcdir)/cpp.texi
INSTALL: $(srcdir)/install1.texi $(srcdir)/install.texi
cd $(srcdir); $(MAKEINFO) -D INSTALLONLY \
- --no-split -o INSTALL install1.texi
+ --no-split --no-headers -o INSTALL install1.texi
#
# Deletion of files made during compilation.
# There are four levels of this:
@@ -2476,8 +2455,7 @@ maintainer-clean:
$(MAKE) INTL_DISTCLEAN= INTL_CLEAN= INTL_MOSTLYCLEAN= \
intl.maintainer-clean lang.maintainer-clean distclean
-rm -f c-parse.y c-gperf.h
- -rm -f c-parse.c c-parse.h c-parse.output
- -rm -f cexp.c cexp.output TAGS
+ -rm -f c-parse.c c-parse.h c-parse.output TAGS
-rm -f cpp.info* cpp.??s cpp.*aux
-rm -f gcc.info* gcc.??s gcc.*aux
#
@@ -2661,7 +2639,7 @@ install-info: doc installdirs lang.install-info
-chmod a-x $(infodir)/cpp.info* $(infodir)/gcc.info*
# Install the man pages.
-install-man: installdirs $(srcdir)/gcc.1 $(srcdir)/cccp.1 lang.install-man
+install-man: installdirs $(srcdir)/gcc.1 $(srcdir)/cpp.1 lang.install-man
-if [ -f gcc-cross$(exeext) ] ; then \
rm -f $(man1dir)/$(GCC_CROSS_NAME)$(manext); \
$(INSTALL_DATA) $(srcdir)/gcc.1 $(man1dir)/$(GCC_CROSS_NAME)$(manext); \
@@ -2671,9 +2649,9 @@ install-man: installdirs $(srcdir)/gcc.1 $(srcdir)/cccp.1 lang.install-man
$(INSTALL_DATA) $(srcdir)/gcc.1 $(man1dir)/$(GCC_INSTALL_NAME)$(manext); \
chmod a-x $(man1dir)/$(GCC_INSTALL_NAME)$(manext); \
fi
- -rm -f $(man1dir)/cccp$(manext)
- -$(INSTALL_DATA) $(srcdir)/cccp.1 $(man1dir)/cccp$(manext)
- -chmod a-x $(man1dir)/cccp$(manext)
+ -rm -f $(man1dir)/cpp$(manext)
+ -$(INSTALL_DATA) $(srcdir)/cpp.1 $(man1dir)/cpp$(manext)
+ -chmod a-x $(man1dir)/cpp$(manext)
# Install the library.
install-libgcc: libgcc.a installdirs
@@ -2782,7 +2760,7 @@ uninstall: intl.uninstall lang.uninstall $(UNINSTALL_CPP)
-rm -rf $(bindir)/$(GCOV_INSTALL_NAME)$(exeext)
-rm -rf $(man1dir)/$(GCC_INSTALL_NAME)$(manext)
-rm -rf $(man1dir)/$(GCC_CROSS_NAME)$(manext)
- -rm -rf $(man1dir)/cccp$(manext)
+ -rm -rf $(man1dir)/cpp$(manext)
-rm -rf $(man1dir)/protoize$(manext)
-rm -rf $(man1dir)/unprotoize$(manext)
-rm -f $(infodir)/cpp.info* $(infodir)/gcc.info*
@@ -2898,7 +2876,7 @@ check-objc: testsuite/site.exp
TAGS: force
cd $(srcdir); \
mkdir tmp-tags; \
- mv -f c-parse.[ch] cexp.c =*.[chy] tmp-tags; \
+ mv -f c-parse.[ch] =*.[chy] tmp-tags; \
etags *.y *.h *.c; \
mv tmp-tags/* .; \
rmdir tmp-tags
@@ -2918,8 +2896,7 @@ distdir-cvs: force
# This target exists to do the initial work before the language specific
# stuff gets done.
distdir-start: doc $(srcdir)/INSTALL $(srcdir)/c-parse.y $(srcdir)/c-gperf.h \
- $(srcdir)/c-parse.c $(srcdir)/cexp.c $(srcdir)/config.in \
- $(srcdir)/version.c TAGS
+ $(srcdir)/c-parse.c $(srcdir)/config.in $(srcdir)/version.c TAGS
@case '$(USE_NLS)' in \
yes) ;; \
*) echo "configure with --enable-nls before making a distribution"; \
@@ -2948,7 +2925,7 @@ distdir-start: doc $(srcdir)/INSTALL $(srcdir)/c-parse.y $(srcdir)/c-gperf.h \
test -f $(srcdir)/$$file && $(LN_S) $(srcdir)/$$file tmp; \
done
if test "$(srcdir)" != "." ; then \
- for file in c-parse.c cexp.c ; do \
+ for file in c-parse.c ; do \
test -f ./$$file && $(LN_S) ../$$file tmp; \
done; \
fi
@@ -2998,8 +2975,7 @@ distdir: distdir-cvs distdir-start intl.distdir intl.distdir-fixup \
# The -P option assumes this is GNU diff.
diff:
diff -rc2P -x c-parse.y -x c-parse.c -x c-parse.h -x c-gperf.h \
- -x cexp.c -x -x TAGS -x INSTALL \
- -x configure -x config.in \
+ -x TAGS -x INSTALL -x configure -x config.in \
-x "gcc.??" -x "gcc.??s" -x gcc.aux -x "gcc.info*" \
-x "cpp.??" -x "cpp.??s" -x cpp.aux -x "cpp.info*" \
$(LANG_DIFF_EXCLUDES) \
diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4
index 31230b0724f..a0c1c3be7dc 100644
--- a/gcc/aclocal.m4
+++ b/gcc/aclocal.m4
@@ -503,7 +503,6 @@ AC_DEFUN(AM_GNU_GETTEXT,
AC_REQUIRE([AC_TYPE_OFF_T])dnl
AC_REQUIRE([AC_TYPE_SIZE_T])dnl
AC_REQUIRE([AC_FUNC_ALLOCA])dnl
- AC_REQUIRE([AC_FUNC_MMAP])dnl
AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
unistd.h sys/param.h])
@@ -762,3 +761,55 @@ if test $ac_cv_func_mmap_anywhere = yes; then
[Define if mmap can get us zeroed pages from /dev/zero.])
fi
])
+
+# Check whether mmap can map a plain file, without MAP_FIXED.
+AC_DEFUN([AC_FUNC_MMAP_FILE],
+[AC_REQUIRE([AC_FUNC_MMAP_ANYWHERE])dnl
+AC_CACHE_CHECK(for working mmap of a file, ac_cv_func_mmap_file,
+[# Create a file one thousand bytes long.
+for i in 1 2 3 4 5 6 7 8 9 0
+do for j in 1 2 3 4 5 6 7 8 9 0
+do echo $i $j xxxxx
+done
+done > conftestdata$$
+
+AC_TRY_RUN([
+/* Test by Zack Weinberg. Modified from MMAP_ANYWHERE test by
+ Richard Henderson and Alexandre Oliva.
+ Check whether read-only mmap of a plain file works. */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+int main()
+{
+ char *x;
+ int fd;
+ struct stat st;
+
+ fd = open("conftestdata$$", O_RDONLY);
+ if (fd < 0)
+ exit(1);
+
+ if (fstat (fd, &st))
+ exit(2);
+
+ x = (char*)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (x == (char *) -1)
+ exit(3);
+
+ if (x[0] != '1' || x[1] != ' ' || x[2] != '1' || x[3] != ' ')
+ exit(4);
+
+ if (munmap(x, st.st_size) < 0)
+ exit(5);
+
+ exit(0);
+}], ac_cv_func_mmap_file=yes, ac_cv_func_mmap_file=no,
+ac_cv_func_mmap_file=no)])
+if test $ac_cv_func_mmap_file = yes; then
+ AC_DEFINE(HAVE_MMAP_FILE, 1,
+ [Define if read-only mmap of a plain file works.])
+fi
+])
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 257d6c8e383..ad1cc0d8da9 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -450,6 +450,7 @@ extern rtx emit_block_insn_before PARAMS ((rtx, rtx, basic_block));
/* In predict.c */
extern void estimate_probability PARAMS ((struct loops *));
+extern void expected_value_to_br_prob PARAMS ((void));
/* In flow.c */
extern void reorder_basic_blocks PARAMS ((void));
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index 35ab3c8a5fe..7812ff1bab9 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -690,8 +690,7 @@ fixup_reorder_chain ()
BASIC_BLOCK (nb->index)->local_set = 0;
nb->aux = xcalloc (1, sizeof (struct reorder_block_def));
- REORDER_BLOCK_INDEX (BASIC_BLOCK (n_basic_blocks - 1))
- = REORDER_BLOCK_INDEX (bbi) + 1;
+ REORDER_BLOCK_INDEX (nb) = REORDER_BLOCK_INDEX (bbi) + 1;
/* Relink to new block. */
nb->succ = bbi->succ;
nb->succ->src = nb;
@@ -831,6 +830,22 @@ reorder_basic_blocks ()
REORDER_BLOCK_EFF_HEAD (bbi) = NEXT_INSN (prev_eff_end);
}
}
+
+ /* If we've not got epilogue in RTL, we must fallthru to the exit.
+ Force the last block to be at the end. */
+ /* ??? Some ABIs (e.g. MIPS) require the return insn to be at the
+ end of the function for stack unwinding purposes. */
+
+#ifndef HAVE_epilogue
+#define HAVE_epilogue 0
+#endif
+
+ if (! HAVE_epilogue)
+ {
+ basic_block last = BASIC_BLOCK (n_basic_blocks - 1);
+ REORDER_BLOCK_INDEX (last) = n_basic_blocks - 1;
+ REORDER_BLOCK_FLAGS (last) |= REORDER_BLOCK_VISITED;
+ }
make_reorder_chain (BASIC_BLOCK (0));
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 9159a1b2c8f..f288916f790 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -103,6 +103,7 @@ static rtx expand_builtin_alloca PARAMS ((tree, rtx));
static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
static rtx expand_builtin_frame_address PARAMS ((tree));
static tree stabilize_va_list PARAMS ((tree, int));
+static rtx expand_builtin_expect PARAMS ((tree, rtx));
/* Return the alignment in bits of EXP, a pointer valued expression.
But don't return more than MAX_ALIGN no matter what.
@@ -378,8 +379,8 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
calls may traverse the arc back to this label. */
current_function_has_nonlocal_label = 1;
- nonlocal_goto_handler_labels =
- gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
+ nonlocal_goto_handler_labels
+ = gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
/* Clobber the FP when we get here, so we have to make sure it's
marked as used by this function. */
@@ -2306,6 +2307,48 @@ expand_builtin_ffs (arglist, target, subtarget)
abort ();
return target;
}
+
+/* Expand a call to __builtin_expect. We return our argument and
+ emit a NOTE_INSN_EXPECTED_VALUE note. */
+
+static rtx
+expand_builtin_expect (arglist, target)
+ tree arglist;
+ rtx target;
+{
+ tree exp, c;
+ rtx note, rtx_c;
+
+ if (arglist == NULL_TREE
+ || TREE_CHAIN (arglist) == NULL_TREE)
+ return const0_rtx;
+ exp = TREE_VALUE (arglist);
+ c = TREE_VALUE (TREE_CHAIN (arglist));
+
+ if (TREE_CODE (c) != INTEGER_CST)
+ {
+ error ("second arg to `__builtin_expect' must be a constant");
+ c = integer_zero_node;
+ }
+
+ target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
+
+ /* Don't bother with expected value notes for integral constants. */
+ if (GET_CODE (target) != CONST_INT)
+ {
+ /* We do need to force this into a register so that we can be
+ moderately sure to be able to correctly interpret the branch
+ condition later. */
+ target = force_reg (GET_MODE (target), target);
+
+ rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
+
+ note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
+ NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
+ }
+
+ return target;
+}
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
@@ -2581,6 +2624,8 @@ expand_builtin (exp, target, subtarget, mode, ignore)
return expand_builtin_va_end (arglist);
case BUILT_IN_VA_COPY:
return expand_builtin_va_copy (arglist);
+ case BUILT_IN_EXPECT:
+ return expand_builtin_expect (arglist, target);
default: /* just do library call, if unknown builtin */
error ("built-in function `%s' not currently supported",
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 506bc4102c5..308257fa859 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -79,6 +79,7 @@ DEF_BUILTIN(BUILT_IN_VARARGS_START)
DEF_BUILTIN(BUILT_IN_STDARG_START)
DEF_BUILTIN(BUILT_IN_VA_END)
DEF_BUILTIN(BUILT_IN_VA_COPY)
+DEF_BUILTIN(BUILT_IN_EXPECT)
/* C++ extensions */
DEF_BUILTIN(BUILT_IN_NEW)
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 1033035db23..32b2ede864b 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -981,6 +981,8 @@ decl_attributes (node, attributes, prefix_attributes)
break;
}
id = get_identifier (TREE_STRING_POINTER (id));
+ /* This counts as a use of the object pointed to. */
+ TREE_USED (id) = 1;
if (TREE_CODE (decl) == FUNCTION_DECL)
DECL_INITIAL (decl) = error_mark_node;
@@ -3767,6 +3769,16 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
endlink))),
BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL_PTR);
+ /* ??? Ought to be `T __builtin_expect(T, T)' for any type T. */
+ builtin_function ("__builtin_expect",
+ build_function_type (long_integer_type_node,
+ tree_cons (NULL_TREE,
+ long_integer_type_node,
+ tree_cons (NULL_TREE,
+ long_integer_type_node,
+ endlink))),
+ BUILT_IN_EXPECT, BUILT_IN_NORMAL, NULL_PTR);
+
/* Currently under experimentation. */
builtin_function ("__builtin_memcpy", memcpy_ftype, BUILT_IN_MEMCPY,
BUILT_IN_NORMAL, "memcpy");
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index df1d707fa6c..4d175cb36de 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -2860,13 +2860,14 @@ lookup_name_current_level (name)
}
/* Mark ARG for GC. */
+
static void
mark_binding_level (arg)
void *arg;
{
struct binding_level *level = *(struct binding_level **) arg;
- while (level)
+ for (; level != 0; level = level->level_chain)
{
ggc_mark_tree (level->names);
ggc_mark_tree (level->tags);
@@ -2874,7 +2875,6 @@ mark_binding_level (arg)
ggc_mark_tree (level->blocks);
ggc_mark_tree (level->this_block);
ggc_mark_tree (level->parm_order);
- level = level->level_chain;
}
}
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index 2f8a8403d69..8498e5f9607 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -680,7 +680,7 @@ check_newline ()
}
else if (!strcmp (name, "ident"))
{
- /* #ident. The pedantic warning is now in cccp.c. */
+ /* #ident. The pedantic warning is now in cpp. */
/* Here we have just seen `#ident '.
A string constant should follow. */
@@ -1625,7 +1625,7 @@ yylex ()
floatflag = AFTER_EXPON;
break; /* start of exponent */
}
- else if (c >= 'a')
+ else if (c >= 'a' && c <= 'f')
{
c = c - 'a' + 10;
}
diff --git a/gcc/calls.c b/gcc/calls.c
index 2592a8e7fb3..12dea75584a 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -185,9 +185,8 @@ static void store_unaligned_arguments_into_pseudos PARAMS ((struct arg_data *,
static int finalize_must_preallocate PARAMS ((int, int,
struct arg_data *,
struct args_size *));
-static void precompute_arguments PARAMS ((int, int, int,
- struct arg_data *,
- struct args_size *));
+static void precompute_arguments PARAMS ((int, int,
+ struct arg_data *));
static int compute_argument_block_size PARAMS ((int,
struct args_size *,
int));
@@ -1417,23 +1416,17 @@ compute_argument_block_size (reg_parm_stack_space, args_size,
FLAGS is mask of ECF_* constants.
- MUST_PREALLOCATE indicates that we must preallocate stack space for
- any stack arguments.
-
NUM_ACTUALS is the number of arguments.
ARGS is an array containing information for each argument; this routine
- fills in the INITIAL_VALUE and VALUE fields for each precomputed argument.
-
- ARGS_SIZE contains information about the size of the arg list. */
+ fills in the INITIAL_VALUE and VALUE fields for each precomputed argument.
+ */
static void
-precompute_arguments (flags, must_preallocate, num_actuals, args, args_size)
+precompute_arguments (flags, num_actuals, args)
int flags;
- int must_preallocate;
int num_actuals;
struct arg_data *args;
- struct args_size *args_size;
{
int i;
@@ -1448,15 +1441,13 @@ precompute_arguments (flags, must_preallocate, num_actuals, args, args_size)
on the stack, then we must precompute any parameter which contains a
function call which will store arguments on the stack.
Otherwise, evaluating the parameter may clobber previous parameters
- which have already been stored into the stack. */
+ which have already been stored into the stack. (we have code to avoid
+ such case by saving the ougoing stack arguments, but it results in
+ worse code) */
for (i = 0; i < num_actuals; i++)
if ((flags & (ECF_CONST | ECF_PURE))
- || ((args_size->var != 0 || args_size->constant != 0)
- && calls_function (args[i].tree_value, 1))
- || (must_preallocate
- && (args_size->var != 0 || args_size->constant != 0)
- && calls_function (args[i].tree_value, 0)))
+ || calls_function (args[i].tree_value, !ACCUMULATE_OUTGOING_ARGS))
{
/* If this is an addressable type, we cannot pre-evaluate it. */
if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
@@ -2476,13 +2467,12 @@ expand_call (exp, target, ignore)
|| reg_mentioned_p (virtual_outgoing_args_rtx,
structure_value_addr))
&& (args_size.var
- || (!ACCUMULATE_OUTGOING_ARGS && args_size.constant)
- ))
+ || (!ACCUMULATE_OUTGOING_ARGS && args_size.constant)))
structure_value_addr = copy_to_reg (structure_value_addr);
/* Precompute any arguments as needed. */
- precompute_arguments (flags, must_preallocate, num_actuals,
- args, &args_size);
+ if (pass)
+ precompute_arguments (flags, num_actuals, args);
/* Now we are about to start emitting insns that can be deleted
if a libcall is deleted. */
@@ -2490,11 +2480,14 @@ expand_call (exp, target, ignore)
start_sequence ();
old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
-
+ /* The argument block when performing a sibling call is the
+ incoming argument block. */
+ if (pass == 0)
+ argblock = virtual_incoming_args_rtx;
/* If we have no actual push instructions, or shouldn't use them,
make space for all args right now. */
- if (args_size.var != 0)
+ else if (args_size.var != 0)
{
if (old_stack_level == 0)
{
@@ -2529,24 +2522,24 @@ expand_call (exp, target, ignore)
{
if (ACCUMULATE_OUTGOING_ARGS)
{
- /* Since the stack pointer will never be pushed, it is possible
- for the evaluation of a parm to clobber something we have
- already written to the stack. Since most function calls on
- RISC machines do not use the stack, this is uncommon, but
- must work correctly.
+ /* Since the stack pointer will never be pushed, it is
+ possible for the evaluation of a parm to clobber
+ something we have already written to the stack.
+ Since most function calls on RISC machines do not use
+ the stack, this is uncommon, but must work correctly.
Therefore, we save any area of the stack that was already
- written and that we are using. Here we set up to do this by
- making a new stack usage map from the old one. The actual
- save will be done by store_one_arg.
+ written and that we are using. Here we set up to do this
+ by making a new stack usage map from the old one. The
+ actual save will be done by store_one_arg.
Another approach might be to try to reorder the argument
evaluations to avoid this conflicting stack usage. */
#ifndef OUTGOING_REG_PARM_STACK_SPACE
- /* Since we will be writing into the entire argument area, the
- map must be allocated for its entire size, not just the part
- that is the responsibility of the caller. */
+ /* Since we will be writing into the entire argument area,
+ the map must be allocated for its entire size, not just
+ the part that is the responsibility of the caller. */
needed += reg_parm_stack_space;
#endif
@@ -2557,7 +2550,8 @@ expand_call (exp, target, ignore)
highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
needed);
#endif
- stack_usage_map = (char *) alloca (highest_outgoing_arg_in_use);
+ stack_usage_map
+ = (char *) alloca (highest_outgoing_arg_in_use);
if (initial_highest_arg_in_use)
bcopy (initial_stack_usage_map, stack_usage_map,
@@ -2569,9 +2563,9 @@ expand_call (exp, target, ignore)
- initial_highest_arg_in_use));
needed = 0;
- /* The address of the outgoing argument list must not be copied
- to a register here, because argblock would be left pointing
- to the wrong place after the call to
+ /* The address of the outgoing argument list must not be
+ copied to a register here, because argblock would be left
+ pointing to the wrong place after the call to
allocate_dynamic_stack_space below. */
argblock = virtual_outgoing_args_rtx;
@@ -2600,63 +2594,53 @@ expand_call (exp, target, ignore)
else
argblock = push_block (GEN_INT (needed), 0, 0);
- /* We only really need to call `copy_to_reg' in the case where
- push insns are going to be used to pass ARGBLOCK to a function
- call in ARGS. In that case, the stack pointer changes value
- from the allocation point to the call point, and hence
- the value of VIRTUAL_OUTGOING_ARGS_RTX changes as well.
- But might as well always do it. */
+ /* We only really need to call `copy_to_reg' in the case
+ where push insns are going to be used to pass ARGBLOCK
+ to a function call in ARGS. In that case, the stack
+ pointer changes value from the allocation point to the
+ call point, and hence the value of
+ VIRTUAL_OUTGOING_ARGS_RTX changes as well. But might
+ as well always do it. */
argblock = copy_to_reg (argblock);
- }
- }
- }
-
- /* The argument block when performing a sibling call is the
- incoming argument block. */
- if (pass == 0)
- {
- rtx temp = plus_constant (arg_pointer_rtx,
- FIRST_PARM_OFFSET (current_function_decl));
- argblock = force_reg (Pmode, force_operand (temp, NULL_RTX));
- }
- if (ACCUMULATE_OUTGOING_ARGS)
- {
- /* The save/restore code in store_one_arg handles all cases except one:
- a constructor call (including a C function returning a BLKmode struct)
- to initialize an argument. */
- if (stack_arg_under_construction)
- {
+ /* The save/restore code in store_one_arg handles all
+ cases except one:
+ a constructor call (including a C function returning
+ a BLKmode struct) to initialize an argument. */
+ if (stack_arg_under_construction)
+ {
#ifndef OUTGOING_REG_PARM_STACK_SPACE
- rtx push_size = GEN_INT (reg_parm_stack_space + args_size.constant);
+ rtx push_size = GEN_INT (reg_parm_stack_space + args_size.constant);
#else
- rtx push_size = GEN_INT (args_size.constant);
+ rtx push_size = GEN_INT (args_size.constant);
#endif
- if (old_stack_level == 0)
- {
- emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
- old_pending_adj = pending_stack_adjust;
- pending_stack_adjust = 0;
- /* stack_arg_under_construction says whether a stack arg is
- being constructed at the old stack level. Pushing the stack
- gets a clean outgoing argument block. */
- old_stack_arg_under_construction = stack_arg_under_construction;
- stack_arg_under_construction = 0;
- /* Make a new map for the new argument list. */
- stack_usage_map = (char *)alloca (highest_outgoing_arg_in_use);
- bzero (stack_usage_map, highest_outgoing_arg_in_use);
- highest_outgoing_arg_in_use = 0;
+ if (old_stack_level == 0)
+ {
+ emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
+ old_pending_adj = pending_stack_adjust;
+ pending_stack_adjust = 0;
+ /* stack_arg_under_construction says whether a stack arg is
+ being constructed at the old stack level. Pushing the stack
+ gets a clean outgoing argument block. */
+ old_stack_arg_under_construction = stack_arg_under_construction;
+ stack_arg_under_construction = 0;
+ /* Make a new map for the new argument list. */
+ stack_usage_map = (char *)alloca (highest_outgoing_arg_in_use);
+ bzero (stack_usage_map, highest_outgoing_arg_in_use);
+ highest_outgoing_arg_in_use = 0;
+ }
+ allocate_dynamic_stack_space (push_size, NULL_RTX, BITS_PER_UNIT);
+ }
+ /* If argument evaluation might modify the stack pointer, copy the
+ address of the argument list to a register. */
+ for (i = 0; i < num_actuals; i++)
+ if (args[i].pass_on_stack)
+ {
+ argblock = copy_addr_to_reg (argblock);
+ break;
+ }
}
- allocate_dynamic_stack_space (push_size, NULL_RTX, BITS_PER_UNIT);
}
- /* If argument evaluation might modify the stack pointer, copy the
- address of the argument list to a register. */
- for (i = 0; i < num_actuals; i++)
- if (args[i].pass_on_stack)
- {
- argblock = copy_addr_to_reg (argblock);
- break;
- }
}
compute_argument_addresses (args, argblock, num_actuals);
@@ -2719,7 +2703,7 @@ expand_call (exp, target, ignore)
#ifdef REG_PARM_STACK_SPACE
/* Save the fixed argument area if it's part of the caller's frame and
is clobbered by argument setup for this call. */
- if (ACCUMULATE_OUTGOING_ARGS)
+ if (ACCUMULATE_OUTGOING_ARGS && pass)
save_area = save_fixed_argument_area (reg_parm_stack_space, argblock,
&low_to_save, &high_to_save);
#endif
@@ -2732,7 +2716,7 @@ expand_call (exp, target, ignore)
for (i = 0; i < num_actuals; i++)
if (args[i].reg == 0 || args[i].pass_on_stack)
- store_one_arg (&args[i], argblock, flags & ECF_MAY_BE_ALLOCA,
+ store_one_arg (&args[i], argblock, flags,
args_size.var != 0, reg_parm_stack_space);
/* If we have a parm that is passed in registers but not in memory
@@ -2747,7 +2731,7 @@ expand_call (exp, target, ignore)
if (reg_parm_seen)
for (i = 0; i < num_actuals; i++)
if (args[i].partial != 0 && ! args[i].pass_on_stack)
- store_one_arg (&args[i], argblock, flags & ECF_MAY_BE_ALLOCA,
+ store_one_arg (&args[i], argblock, flags,
args_size.var != 0, reg_parm_stack_space);
#ifdef PREFERRED_STACK_BOUNDARY
@@ -3047,14 +3031,13 @@ expand_call (exp, target, ignore)
stack_usage_map = initial_stack_usage_map;
sibcall_failure = 1;
}
- else if (ACCUMULATE_OUTGOING_ARGS)
+ else if (ACCUMULATE_OUTGOING_ARGS && pass)
{
#ifdef REG_PARM_STACK_SPACE
if (save_area)
{
restore_fixed_argument_area (save_area, argblock,
high_to_save, low_to_save);
- sibcall_failure = 1;
}
#endif
@@ -3075,7 +3058,6 @@ expand_call (exp, target, ignore)
validize_mem (args[i].save_area),
GEN_INT (args[i].size.constant),
PARM_BOUNDARY);
- sibcall_failure = 1;
}
highest_outgoing_arg_in_use = initial_highest_arg_in_use;
@@ -3605,8 +3587,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
{
if (ACCUMULATE_OUTGOING_ARGS)
{
- /* If this is being stored into a pre-allocated, fixed-size, stack
- area, save any previous data at that location. */
+ /* If this is being stored into a pre-allocated, fixed-size,
+ stack area, save any previous data at that location. */
#ifdef ARGS_GROW_DOWNWARD
/* stack_slot is negative, but we want to index stack_usage_map
@@ -3620,16 +3602,18 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
for (i = lower_bound; i < upper_bound; i++)
if (stack_usage_map[i]
- /* Don't store things in the fixed argument area at this point;
- it has already been saved. */
+ /* Don't store things in the fixed argument area at this
+ point; it has already been saved. */
&& i > reg_parm_stack_space)
break;
if (i != upper_bound)
{
- /* We need to make a save area. See what mode we can make it. */
+ /* We need to make a save area. See what mode we can make
+ it. */
enum machine_mode save_mode
- = mode_for_size (argvec[argnum].size.constant * BITS_PER_UNIT,
+ = mode_for_size (argvec[argnum].size.constant
+ * BITS_PER_UNIT,
MODE_INT, 1);
rtx stack_area
= gen_rtx_MEM
@@ -3985,11 +3969,11 @@ target_for_arg (type, size, args_addr, offset)
FNDECL is the declaration of the function we are calling. */
static void
-store_one_arg (arg, argblock, may_be_alloca, variable_size,
+store_one_arg (arg, argblock, flags, variable_size,
reg_parm_stack_space)
struct arg_data *arg;
rtx argblock;
- int may_be_alloca;
+ int flags;
int variable_size ATTRIBUTE_UNUSED;
int reg_parm_stack_space;
{
@@ -4006,7 +3990,7 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
this argument. */
push_temp_slots ();
- if (ACCUMULATE_OUTGOING_ARGS)
+ if (ACCUMULATE_OUTGOING_ARGS && !(flags & ECF_SIBCALL))
{
/* If this is being stored into a pre-allocated, fixed-size, stack area,
save any previous data at that location. */
@@ -4134,7 +4118,7 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
/* Don't allow anything left on stack from computation
of argument to alloca. */
- if (may_be_alloca)
+ if (flags & ECF_MAY_BE_ALLOCA)
do_pending_stack_adjust ();
if (arg->value == arg->stack)
diff --git a/gcc/cccp.1 b/gcc/cccp.1
deleted file mode 100644
index 84eb19ede54..00000000000
--- a/gcc/cccp.1
+++ /dev/null
@@ -1,674 +0,0 @@
-.\" Copyright (c) 1991, 1992, 1993 Free Software Foundation \-*-Text-*-
-.\" See section COPYING for conditions for redistribution
-.TH cpp 1 "30apr1993" "GNU Tools" "GNU Tools"
-.SH NAME
-cccp, cpp \- The GNU C-Compatible Compiler Preprocessor.
-.SH SYNOPSIS
-.hy 0
-.na
-.TP
-.B cccp
-.RB "[\|" \-$ "\|]"
-.RB "[\|" \-A \c
-.I predicate\c
-.RB [ (\c
-.I value\c
-.BR ) ]\|]
-.RB "[\|" \-C "\|]"
-.RB "[\|" \-D \c
-.I name\c
-.RB [ =\c
-.I definition\c
-\&]\|]
-.RB "[\|" \-dD "\|]"
-.RB "[\|" \-dM "\|]"
-.RB "[\|" "\-I\ "\c
-.I directory\c
-\&\|]
-.RB "[\|" \-H "\|]"
-.RB "[\|" \-I\- "\|]"
-.RB "[\|" "\-imacros\ "\c
-.I file\c
-\&\|]
-.RB "[\|" "\-include\ "\c
-.I file\c
-\&\|]
-.RB "[\|" "\-idirafter\ "\c
-.I dir\c
-\&\|]
-.RB "[\|" "\-iprefix\ "\c
-.I prefix\c
-\&\|]
-.RB "[\|" "\-iwithprefix\ "\c
-.I dir\c
-\&\|]
-.RB "[\|" \-lang\-c "\|]"
-.RB "[\|" \-lang\-c++ "\|]"
-.RB "[\|" \-lang\-objc "\|]"
-.RB "[\|" \-lang\-objc++ "\|]"
-.RB "[\|" \-lint "\|]"
-.RB "[\|" \-M\ [ \-MG "\|]]"
-.RB "[\|" \-MM\ [ \-MG "\|]]"
-.RB "[\|" \-MD\ \c
-.I file\ \c
-\&\|]
-.RB "[\|" \-MMD\ \c
-.I file\ \c
-\&\|]
-.RB "[\|" \-nostdinc "\|]"
-.RB "[\|" \-nostdinc++ "\|]"
-.RB "[\|" \-P "\|]"
-.RB "[\|" \-pedantic "\|]"
-.RB "[\|" \-pedantic\-errors "\|]"
-.RB "[\|" \-traditional "\|]"
-.RB "[\|" \-trigraphs "\|]"
-.RB "[\|" \-U \c
-.I name\c
-\&\|]
-.RB "[\|" \-undef "\|]"
-.RB "[\|" \-Wtrigraphs "\|]"
-.RB "[\|" \-Wcomment "\|]"
-.RB "[\|" \-Wall "\|]"
-.RB "[\|" \-Wtraditional "\|]"
-.br
-.RB "[\|" \c
-.I infile\c
-.RB | \- "\|]"
-.RB "[\|" \c
-.I outfile\c
-.RB | \- "\|]"
-.ad b
-.hy 1
-.SH DESCRIPTION
-The C preprocessor is a \c
-.I macro processor\c
-\& that is used automatically by
-the C compiler to transform your program before actual compilation. It is
-called a macro processor because it allows you to define \c
-.I macros\c
-\&,
-which are brief abbreviations for longer constructs.
-
-The C preprocessor provides four separate facilities that you can use as
-you see fit:
-.TP
-\(bu
-Inclusion of header files. These are files of declarations that can be
-substituted into your program.
-.TP
-\(bu
-Macro expansion. You can define \c
-.I macros\c
-\&, which are abbreviations
-for arbitrary fragments of C code, and then the C preprocessor will
-replace the macros with their definitions throughout the program.
-.TP
-\(bu
-Conditional compilation. Using special preprocessing directives, you
-can include or exclude parts of the program according to various
-conditions.
-.TP
-\(bu
-Line control. If you use a program to combine or rearrange source files into
-an intermediate file which is then compiled, you can use line control
-to inform the compiler of where each source line originally came from.
-.PP
-C preprocessors vary in some details. For a full explanation of the
-GNU C preprocessor, see the
-.B info
-file `\|\c
-.B cpp.info\c
-\&\|', or the manual
-.I The C Preprocessor\c
-\&. Both of these are built from the same documentation source file, `\|\c
-.B cpp.texinfo\c
-\&\|'. The GNU C
-preprocessor provides a superset of the features of ANSI Standard C.
-
-ANSI Standard C requires the rejection of many harmless constructs commonly
-used by today's C programs. Such incompatibility would be inconvenient for
-users, so the GNU C preprocessor is configured to accept these constructs
-by default. Strictly speaking, to get ANSI Standard C, you must use the
-options `\|\c
-.B \-trigraphs\c
-\&\|', `\|\c
-.B \-undef\c
-\&\|' and `\|\c
-.B \-pedantic\c
-\&\|', but in
-practice the consequences of having strict ANSI Standard C make it
-undesirable to do this.
-
-Most often when you use the C preprocessor you will not have to invoke it
-explicitly: the C compiler will do so automatically. However, the
-preprocessor is sometimes useful individually.
-
-When you call the preprocessor individually, either name
-(\c
-.B cpp\c
-\& or \c
-.B cccp\c
-\&) will do\(em\&they are completely synonymous.
-
-The C preprocessor expects two file names as arguments, \c
-.I infile\c
-\& and
-\c
-.I outfile\c
-\&. The preprocessor reads \c
-.I infile\c
-\& together with any other
-files it specifies with `\|\c
-.B #include\c
-\&\|'. All the output generated by the
-combined input files is written in \c
-.I outfile\c
-\&.
-
-Either \c
-.I infile\c
-\& or \c
-.I outfile\c
-\& may be `\|\c
-.B \-\c
-\&\|', which as \c
-.I infile\c
-\&
-means to read from standard input and as \c
-.I outfile\c
-\& means to write to
-standard output. Also, if \c
-.I outfile\c
-\& or both file names are omitted,
-the standard output and standard input are used for the omitted file names.
-.SH OPTIONS
-Here is a table of command options accepted by the C preprocessor.
-These options can also be given when compiling a C program; they are
-passed along automatically to the preprocessor when it is invoked by
-the compiler.
-.TP
-.B \-P
-Inhibit generation of `\|\c
-.B #\c
-\&\|'-lines with line-number information in
-the output from the preprocessor. This might be
-useful when running the preprocessor on something that is not C code
-and will be sent to a program which might be confused by the
-`\|\c
-.B #\c
-\&\|'-lines.
-.TP
-.B \-C
-Do not discard comments: pass them through to the output file.
-Comments appearing in arguments of a macro call will be copied to the
-output before the expansion of the macro call.
-.TP
-.B \-traditional
-Try to imitate the behavior of old-fashioned C, as opposed to ANSI C.
-.TP
-.B \-trigraphs
-Process ANSI standard trigraph sequences. These are three-character
-sequences, all starting with `\|\c
-.B ??\c
-\&\|', that are defined by ANSI C to
-stand for single characters. For example, `\|\c
-.B ??/\c
-\&\|' stands for
-`\|\c
-.BR "\e" "\|',"
-so `\|\c
-.B '??/n'\c
-\&\|' is a character constant for a newline.
-Strictly speaking, the GNU C preprocessor does not support all
-programs in ANSI Standard C unless `\|\c
-.B \-trigraphs\c
-\&\|' is used, but if
-you ever notice the difference it will be with relief.
-
-You don't want to know any more about trigraphs.
-.TP
-.B \-pedantic
-Issue warnings required by the ANSI C standard in certain cases such
-as when text other than a comment follows `\|\c
-.B #else\c
-\&\|' or `\|\c
-.B #endif\c
-\&\|'.
-.TP
-.B \-pedantic\-errors
-Like `\|\c
-.B \-pedantic\c
-\&\|', except that errors are produced rather than
-warnings.
-.TP
-.B \-Wtrigraphs
-Warn if any trigraphs are encountered (assuming they are enabled).
-.TP
-.B \-Wcomment
-.TP
-.B \-Wcomments
-Warn whenever a comment-start sequence `\|\c
-.B /*\c
-\&\|' appears in a comment.
-(Both forms have the same effect).
-.TP
-.B \-Wall
-Requests both `\|\c
-.B \-Wtrigraphs\c
-\&\|' and `\|\c
-.B \-Wcomment\c
-\&\|' (but not
-`\|\c
-.B \-Wtraditional\c
-\&\|').
-.TP
-.B \-Wtraditional
-Warn about certain constructs that behave differently in traditional and
-ANSI C.
-.TP
-.BI "\-I " directory\c
-\&
-Add the directory \c
-.I directory\c
-\& to the end of the list of
-directories to be searched for header files.
-This can be used to override a system header file, substituting your
-own version, since these directories are searched before the system
-header file directories. If you use more than one `\|\c
-.B \-I\c
-\&\|' option,
-the directories are scanned in left-to-right order; the standard
-system directories come after.
-.TP
-.B \-I\-
-Any directories specified with `\|\c
-.B \-I\c
-\&\|' options before the `\|\c
-.B \-I\-\c
-\&\|'
-option are searched only for the case of `\|\c
-.B #include "\c
-.I file\c
-\&"\c
-\&\|';
-they are not searched for `\|\c
-.B #include <\c
-.I file\c
-\&>\c
-\&\|'.
-
-If additional directories are specified with `\|\c
-.B \-I\c
-\&\|' options after
-the `\|\c
-.B \-I\-\c
-\&\|', these directories are searched for all `\|\c
-.B #include\c
-\&\|'
-directives.
-
-In addition, the `\|\c
-.B \-I\-\c
-\&\|' option inhibits the use of the current
-directory as the first search directory for `\|\c
-.B #include "\c
-.I file\c
-\&"\c
-\&\|'.
-Therefore, the current directory is searched only if it is requested
-explicitly with `\|\c
-.B \-I.\c
-\&\|'. Specifying both `\|\c
-.B \-I\-\c
-\&\|' and `\|\c
-.B \-I.\c
-\&\|'
-allows you to control precisely which directories are searched before
-the current one and which are searched after.
-.TP
-.B \-nostdinc
-Do not search the standard system directories for header files.
-Only the directories you have specified with `\|\c
-.B \-I\c
-\&\|' options
-(and the current directory, if appropriate) are searched.
-.TP
-.B \-nostdinc++
-Do not search for header files in the C++ specific standard
-directories, but do still search the other standard directories.
-(This option is used when building libg++.)
-.TP
-.BI "\-D " "name"\c
-\&
-Predefine \c
-.I name\c
-\& as a macro, with definition `\|\c
-.B 1\c
-\&\|'.
-.TP
-.BI "\-D " "name" = definition
-\&
-Predefine \c
-.I name\c
-\& as a macro, with definition \c
-.I definition\c
-\&.
-There are no restrictions on the contents of \c
-.I definition\c
-\&, but if
-you are invoking the preprocessor from a shell or shell-like program
-you may need to use the shell's quoting syntax to protect characters
-such as spaces that have a meaning in the shell syntax. If you use more than
-one `\|\c
-.B \-D\c
-\&\|' for the same
-.I name\c
-\&, the rightmost definition takes effect.
-.TP
-.BI "\-U " "name"\c
-\&
-Do not predefine \c
-.I name\c
-\&. If both `\|\c
-.B \-U\c
-\&\|' and `\|\c
-.B \-D\c
-\&\|' are
-specified for one name, the `\|\c
-.B \-U\c
-\&\|' beats the `\|\c
-.B \-D\c
-\&\|' and the name
-is not predefined.
-.TP
-.B \-undef
-Do not predefine any nonstandard macros.
-.TP
-.BI "\-A " "name(" value )
-Assert (in the same way as the \c
-.B #assert\c
-\& directive)
-the predicate \c
-.I name\c
-\& with tokenlist \c
-.I value\c
-\&. Remember to escape or quote the parentheses on
-shell command lines.
-
-You can use `\|\c
-.B \-A-\c
-\&\|' to disable all predefined assertions; it also
-undefines all predefined macros.
-.TP
-.B \-dM
-Instead of outputting the result of preprocessing, output a list of
-`\|\c
-.B #define\c
-\&\|' directives for all the macros defined during the
-execution of the preprocessor, including predefined macros. This gives
-you a way of finding out what is predefined in your version of the
-preprocessor; assuming you have no file `\|\c
-.B foo.h\c
-\&\|', the command
-.sp
-.br
-touch\ foo.h;\ cpp\ \-dM\ foo.h
-.br
-.sp
-will show the values of any predefined macros.
-.TP
-.B \-dD
-Like `\|\c
-.B \-dM\c
-\&\|' except in two respects: it does \c
-.I not\c
-\& include the
-predefined macros, and it outputs \c
-.I both\c
-\& the `\|\c
-.B #define\c
-\&\|'
-directives and the result of preprocessing. Both kinds of output go to
-the standard output file.
-.PP
-.TP
-.BR \-M\ [ \-MG ]
-Instead of outputting the result of preprocessing, output a rule
-suitable for \c
-.B make\c
-\& describing the dependencies of the main
-source file. The preprocessor outputs one \c
-.B make\c
-\& rule containing
-the object file name for that source file, a colon, and the names of
-all the included files. If there are many included files then the
-rule is split into several lines using `\|\c
-.B \\\\\c
-\&\|'-newline.
-
-`\|\c
-.B \-MG\c
-\&\|' says to treat missing header files as generated files and assume \c
-they live in the same directory as the source file. It must be specified \c
-in addition to `\|\c
-.B \-M\c
-\&\|'.
-
-This feature is used in automatic updating of makefiles.
-.TP
-.BR \-MM\ [ \-MG ]
-Like `\|\c
-.B \-M\c
-\&\|' but mention only the files included with `\|\c
-.B #include
-"\c
-.I file\c
-\&"\c
-\&\|'. System header files included with `\|\c
-.B #include
-<\c
-.I file\c
-\&>\c
-\&\|' are omitted.
-.TP
-.BI \-MD\ file
-Like `\|\c
-.B \-M\c
-\&\|' but the dependency information is written to `\|\c
-.I file\c
-\&\|'. This is in addition to compiling the file as
-specified\(em\&`\|\c
-.B \-MD\c
-\&\|' does not inhibit ordinary compilation the way
-`\|\c
-.B \-M\c
-\&\|' does.
-
-When invoking gcc, do not specify the `\|\c
-.I file\c
-\&\|' argument. Gcc will create file names made by replacing `\|\c
-.B .c\c
-\&\|' with `\|\c
-.B .d\c
-\&\|' at the end of the input file names.
-
-In Mach, you can use the utility \c
-.B md\c
-\& to merge multiple files
-into a single dependency file suitable for using with the `\|\c
-.B make\c
-\&\|'
-command.
-.TP
-.BI \-MMD\ file
-Like `\|\c
-.B \-MD\c
-\&\|' except mention only user header files, not system
-header files.
-.TP
-.B \-H
-Print the name of each header file used, in addition to other normal
-activities.
-.TP
-.BI "\-imacros " "file"\c
-\&
-Process \c
-.I file\c
-\& as input, discarding the resulting output, before
-processing the regular input file. Because the output generated from
-\c
-.I file\c
-\& is discarded, the only effect of `\|\c
-.B \-imacros \c
-.I file\c
-\&\c
-\&\|' is to
-make the macros defined in \c
-.I file\c
-\& available for use in the main
-input. The preprocessor evaluates any `\|\c
-.B \-D\c
-\&\|' and `\|\c
-.B \-U\c
-\&\|' options
-on the command line before processing `\|\c
-.B \-imacros \c
-.I file\c
-\&\|' \c
-\&.
-.TP
-.BI "\-include " "file"
-Process
-.I file
-as input, and include all the resulting output,
-before processing the regular input file.
-.TP
-.BI "-idirafter " "dir"\c
-\&
-Add the directory \c
-.I dir\c
-\& to the second include path. The directories
-on the second include path are searched when a header file is not found
-in any of the directories in the main include path (the one that
-`\|\c
-.B \-I\c
-\&\|' adds to).
-.TP
-.BI "-iprefix " "prefix"\c
-\&
-Specify \c
-.I prefix\c
-\& as the prefix for subsequent `\|\c
-.B \-iwithprefix\c
-\&\|'
-options.
-.TP
-.BI "-iwithprefix " "dir"\c
-\&
-Add a directory to the second include path. The directory's name is
-made by concatenating \c
-.I prefix\c
-\& and \c
-.I dir\c
-\&, where \c
-.I prefix\c
-\&
-was specified previously with `\|\c
-.B \-iprefix\c
-\&\|'.
-.TP
-.B \-lang-c
-.TP
-.B \-lang-c++
-.TP
-.B \-lang-objc
-.TP
-.B \-lang-objc++
-Specify the source language. `\|\c
-.B \-lang-c++\c
-\&\|' makes the preprocessor
-handle C++ comment syntax, and includes extra default include
-directories for C++, and `\|\c
-.B \-lang-objc\c
-\&\|' enables the Objective C
-`\|\c
-.B #import\c
-\&\|' directive. `\|\c
-.B \-lang-c\c
-\&\|' explicitly turns off both of
-these extensions, and `\|\c
-.B \-lang-objc++\c
-\&\|' enables both.
-
-These options are generated by the compiler driver \c
-.B gcc\c
-\&, but not
-passed from the `\|\c
-.B gcc\c
-\&\|' command line.
-.TP
-.B \-lint
-Look for commands to the program checker \c
-.B lint\c
-\& embedded in
-comments, and emit them preceded by `\|\c
-.B #pragma lint\c
-\&\|'. For example,
-the comment `\|\c
-.B /* NOTREACHED */\c
-\&\|' becomes `\|\c
-.B #pragma lint
-NOTREACHED\c
-\&\|'.
-
-This option is available only when you call \c
-.B cpp\c
-\& directly;
-\c
-.B gcc\c
-\& will not pass it from its command line.
-.TP
-.B \-$
-Forbid the use of `\|\c
-.B $\c
-\&\|' in identifiers. This was formerly required for strict conformance
-to the C Standard before the standard was corrected. \c
-
-This option is available only when you call \c
-.B cpp\c
-\& directly;
-.B gcc\c
-\& will not pass it from its command line.
-.SH "SEE ALSO"
-.RB "`\|" Cpp "\|'"
-entry in
-.B info\c
-\&;
-.I The C Preprocessor\c
-, Richard M. Stallman.
-.br
-.BR gcc "(" 1 ");"
-.RB "`\|" Gcc "\|'"
-entry in
-.B info\c
-\&;
-.I
-Using and Porting GNU CC (for version 2.0)\c
-, Richard M. Stallman.
-.SH COPYING
-Copyright (c) 1991, 1992, 1993 Free Software Foundation, Inc.
-.PP
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-.PP
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the
-entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-.PP
-Permission is granted to copy and distribute translations of this
-manual into another language, under the above conditions for modified
-versions, except that this permission notice may be included in
-translations approved by the Free Software Foundation instead of in
-the original English.
diff --git a/gcc/cccp.c b/gcc/cccp.c
deleted file mode 100644
index e91d8cf1b4c..00000000000
--- a/gcc/cccp.c
+++ /dev/null
@@ -1,11310 +0,0 @@
-/* C Compatible Compiler Preprocessor (CCCP)
- Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000 Free Software Foundation, Inc.
- Written by Paul Rubin, June 1986
- Adapted to ANSI C, Richard Stallman, Jan 1987
-
-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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#include "config.h"
-
-#include "system.h"
-#include <signal.h>
-
-#ifdef HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#endif
-
-typedef unsigned char U_CHAR;
-
-#include "pcp.h"
-#include "intl.h"
-#include "prefix.h"
-#include "version.h"
-
-#ifdef MULTIBYTE_CHARS
-#include "mbchar.h"
-#include <locale.h>
-#endif /* MULTIBYTE_CHARS */
-
-#ifndef GET_ENV_PATH_LIST
-#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
-#endif
-
-#ifndef STANDARD_INCLUDE_DIR
-# define STANDARD_INCLUDE_DIR "/usr/include"
-#endif
-
-/* By default, the suffix for object files is ".o". */
-#ifdef OBJECT_SUFFIX
-# define HAVE_OBJECT_SUFFIX
-#else
-# define OBJECT_SUFFIX ".o"
-#endif
-
-/* VMS-specific definitions */
-#ifdef VMS
-#include <descrip.h>
-#include <ssdef.h>
-#include <syidef.h>
-#define open(fname,mode,prot) VMS_open (fname,mode,prot)
-#define fopen(fname,mode) VMS_fopen (fname,mode)
-#define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
-#define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
-#define fwrite(ptr,size,nitems,stream) VMS_fwrite (ptr,size,nitems,stream)
-static int VMS_fstat (), VMS_stat ();
-static int VMS_open ();
-static FILE *VMS_fopen ();
-static FILE *VMS_freopen ();
-static size_t VMS_fwrite ();
-static void hack_vms_include_specification ();
-#define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
-#define INO_T_HASH(a) 0
-#define INCLUDE_LEN_FUDGE 12 /* leave room for VMS syntax conversion */
-#endif /* VMS */
-
-/* Windows does not natively support inodes, and neither does MSDOS.
- Cygwin's emulation can generate non-unique inodes, so don't use it. */
-#if (defined (_WIN32) && ! defined (_UWIN)) \
- || defined (__MSDOS__)
-#define INO_T_EQ(a, b) 0
-#endif
-
-#ifndef INO_T_EQ
-#define INO_T_EQ(a, b) ((a) == (b))
-#endif
-
-#ifndef INO_T_HASH
-#define INO_T_HASH(a) (a)
-#endif
-
-#ifndef INCLUDE_LEN_FUDGE
-#define INCLUDE_LEN_FUDGE 0
-#endif
-
-/* External declarations. */
-
-HOST_WIDEST_INT parse_escape PARAMS ((char **, HOST_WIDEST_INT));
-HOST_WIDEST_INT parse_c_expression PARAMS ((char *, int));
-
-/* Name under which this program was invoked. */
-
-static const char *progname;
-
-/* Nonzero means use extra default include directories for C++. */
-
-static int cplusplus;
-
-/* Nonzero means handle cplusplus style comments */
-
-static int cplusplus_comments;
-
-/* Nonzero means handle #import, for objective C. */
-
-static int objc;
-
-/* Nonzero means this is an assembly file, and allow
- unknown directives, which could be comments. */
-
-static int lang_asm;
-
-/* Current maximum length of directory names in the search path
- for include files. (Altered as we get more of them.) */
-
-static int max_include_len;
-
-/* Nonzero means turn NOTREACHED into #pragma NOTREACHED etc */
-
-static int for_lint = 0;
-
-/* Nonzero means copy comments into the output file. */
-
-static int put_out_comments = 0;
-
-/* Nonzero means don't process the ANSI trigraph sequences. */
-
-static int no_trigraphs = 0;
-
-/* Nonzero means print the names of included files rather than
- the preprocessed output. 1 means just the #include "...",
- 2 means #include <...> as well. */
-
-static int print_deps = 0;
-
-/* Nonzero if missing .h files in -M output are assumed to be generated
- files and not errors. */
-
-static int print_deps_missing_files = 0;
-
-/* Nonzero means print names of header files (-H). */
-
-static int print_include_names = 0;
-
-/* Nonzero means don't output line number information. */
-
-static int no_line_directives;
-
-/* Nonzero means output the text in failing conditionals,
- inside #failed ... #endfailed. */
-
-static int output_conditionals;
-
-/* dump_only means inhibit output of the preprocessed text
- and instead output the definitions of all user-defined
- macros in a form suitable for use as input to cccp.
- dump_names means pass #define and the macro name through to output.
- dump_definitions means pass the whole definition (plus #define) through
-*/
-
-static enum {dump_none, dump_only, dump_names, dump_definitions}
- dump_macros = dump_none;
-
-/* Nonzero means pass all #define and #undef directives which we actually
- process through to the output stream. This feature is used primarily
- to allow cc1 to record the #defines and #undefs for the sake of
- debuggers which understand about preprocessor macros, but it may
- also be useful with -E to figure out how symbols are defined, and
- where they are defined. */
-static int debug_output = 0;
-
-/* Nonzero means pass #include lines through to the output,
- even if they are ifdefed out. */
-static int dump_includes;
-
-/* Nonzero indicates special processing used by the pcp program. The
- special effects of this mode are:
-
- Inhibit all macro expansion, except those inside #if directives.
-
- Process #define directives normally, and output their contents
- to the output file.
-
- Output preconditions to pcp_outfile indicating all the relevant
- preconditions for use of this file in a later cpp run.
-*/
-static FILE *pcp_outfile;
-
-/* Nonzero means we are inside an IF during a -pcp run. In this mode
- macro expansion is done, and preconditions are output for all macro
- uses requiring them. */
-static int pcp_inside_if;
-
-/* Nonzero means never to include precompiled files.
- This is 1 since there's no way now to make precompiled files,
- so it's not worth testing for them. */
-static int no_precomp = 1;
-
-/* Nonzero means give all the error messages the ANSI standard requires. */
-
-int pedantic;
-
-/* Nonzero means try to make failure to fit ANSI C an error. */
-
-static int pedantic_errors;
-
-/* Nonzero means don't print warning messages. -w. */
-
-static int inhibit_warnings = 0;
-
-/* Nonzero means warn if slash-star appears in a slash-star comment,
- or if newline-backslash appears in a slash-slash comment. */
-
-static int warn_comments;
-
-/* Nonzero means warn if a macro argument is (or would be)
- stringified with -traditional. */
-
-static int warn_stringify;
-
-/* Nonzero means warn if there are any trigraphs. */
-
-static int warn_trigraphs;
-
-/* Nonzero means warn if undefined identifiers are evaluated in an #if. */
-
-static int warn_undef;
-
-/* Nonzero means warn if we find white space where it doesn't belong. */
-
-static int warn_white_space;
-
-/* Nonzero means warn if #import is used. */
-
-static int warn_import = 1;
-
-/* Nonzero means turn warnings into errors. */
-
-static int warnings_are_errors;
-
-/* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */
-
-int traditional;
-
-/* Nonzero for the 1989 C Standard, including corrigenda and amendments. */
-
-int c89;
-
-/* Nonzero for the 1999 C Standard. */
-
-int c99;
-
-/* Nonzero causes output not to be done,
- but directives such as #define that have side effects
- are still obeyed. */
-
-static int no_output;
-
-/* Nonzero means we should look for header.gcc files that remap file names. */
-static int remap;
-
-/* Nonzero means this file was included with a -imacros or -include
- command line and should not be recorded as an include file. */
-
-static int no_record_file;
-
-/* Nonzero means that we have finished processing the command line options.
- This flag is used to decide whether or not to issue certain errors
- and/or warnings. */
-
-static int done_initializing = 0;
-
-/* Line where a newline was first seen in a string constant. */
-
-static int multiline_string_line = 0;
-
-/* I/O buffer structure.
- The `fname' field is nonzero for source files and #include files
- and for the dummy text used for -D and -U.
- It is zero for rescanning results of macro expansion
- and for expanding macro arguments. */
-#define INPUT_STACK_MAX 400
-static struct file_buf {
- const char *fname;
- /* Filename specified with #line directive. */
- const char *nominal_fname;
- /* The length of nominal_fname, which may contain embedded NULs. */
- size_t nominal_fname_len;
- /* Include file description. */
- struct include_file *inc;
- /* Record where in the search path this file was found.
- For #include_next. */
- struct file_name_list *dir;
- int lineno;
- int length;
- U_CHAR *buf;
- U_CHAR *bufp;
- /* Macro that this level is the expansion of.
- Included so that we can reenable the macro
- at the end of this level. */
- struct hashnode *macro;
- /* Value of if_stack at start of this file.
- Used to prohibit unmatched #endif (etc) in an include file. */
- struct if_stack *if_stack;
- /* Object to be freed at end of input at this level. */
- U_CHAR *free_ptr;
- /* True if this is a system header file; see is_system_include. */
- char system_header_p;
-} instack[INPUT_STACK_MAX];
-
-static int last_error_tick; /* Incremented each time we print it. */
-static int input_file_stack_tick; /* Incremented when the status changes. */
-
-/* Current nesting level of input sources.
- `instack[indepth]' is the level currently being read. */
-static int indepth = -1;
-#define CHECK_DEPTH(code) \
- if (indepth >= (INPUT_STACK_MAX - 1)) \
- { \
- error_with_line (line_for_error (instack[indepth].lineno), \
- "macro or `#include' recursion too deep"); \
- code; \
- }
-
-/* Current depth in #include directives that use <...>. */
-static int system_include_depth = 0;
-
-typedef struct file_buf FILE_BUF;
-
-/* The output buffer. Its LENGTH field is the amount of room allocated
- for the buffer, not the number of chars actually present. To get
- that, subtract outbuf.buf from outbuf.bufp. */
-
-#define OUTBUF_SIZE 10 /* initial size of output buffer */
-static FILE_BUF outbuf;
-
-/* Grow output buffer OBUF points at
- so it can hold at least NEEDED more chars. */
-
-#define check_expand(OBUF, NEEDED) \
- (((OBUF)->length - ((OBUF)->bufp - (OBUF)->buf) <= (NEEDED)) \
- ? grow_outbuf ((OBUF), (NEEDED)) : 0)
-
-struct file_name_list
- {
- struct file_name_list *next;
- /* If the following is 1, it is a C-language system include
- directory. */
- int c_system_include_path;
- /* Mapping of file names for this directory. */
- struct file_name_map *name_map;
- /* Non-zero if name_map is valid. */
- int got_name_map;
- /* The include directory status. */
- struct stat st;
- /* The include prefix: "" denotes the working directory,
- otherwise fname must end in '/'.
- The actual size is dynamically allocated. */
- char fname[1];
- };
-
-/* #include "file" looks in source file dir, then stack. */
-/* #include <file> just looks in the stack. */
-/* -I directories are added to the end, then the defaults are added. */
-/* The */
-static struct default_include {
- const char *fname; /* The name of the directory. */
- const char *component; /* The component containing the directory */
- int cplusplus; /* Only look here if we're compiling C++. */
- int cxx_aware; /* Includes in this directory don't need to
- be wrapped in extern "C" when compiling
- C++. */
- int included; /* Set if the directory is acceptable. */
-} include_defaults_array[]
-#ifdef INCLUDE_DEFAULTS
- = INCLUDE_DEFAULTS;
-#else
- = {
- /* Pick up GNU C++ specific include files. */
- { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0 },
-#ifdef CROSS_COMPILE
- /* This is the dir for fixincludes. Put it just before
- the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
- /* For cross-compilation, this dir name is generated
- automatically in Makefile.in. */
- { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 },
-#ifdef TOOL_INCLUDE_DIR
- /* This is another place that the target system's headers might be. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 },
-#endif
-#else /* not CROSS_COMPILE */
-#ifdef LOCAL_INCLUDE_DIR
- /* This should be /usr/local/include and should come before
- the fixincludes-fixed header files. */
- { LOCAL_INCLUDE_DIR, 0, 0, 1, 0 },
-#endif
-#ifdef TOOL_INCLUDE_DIR
- /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
- Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 },
-#endif
- /* This is the dir for fixincludes. Put it just before
- the files that we fix. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
- /* Some systems have an extra dir of include files. */
-#ifdef SYSTEM_INCLUDE_DIR
- { SYSTEM_INCLUDE_DIR, 0, 0, 0, 0 },
-#endif
-#ifndef STANDARD_INCLUDE_COMPONENT
-#define STANDARD_INCLUDE_COMPONENT 0
-#endif
- { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 0 },
-#endif /* not CROSS_COMPILE */
- { 0, 0, 0, 0, 0 }
- };
-#endif /* no INCLUDE_DEFAULTS */
-
-/* The code looks at the defaults through this pointer, rather than through
- the constant structure above. This pointer gets changed if an environment
- variable specifies other defaults. */
-static struct default_include *include_defaults = include_defaults_array;
-
-static struct file_name_list *include = 0; /* First dir to search */
- /* First dir to search for <file> */
-/* This is the first element to use for #include <...>.
- If it is 0, use the entire chain for such includes. */
-static struct file_name_list *first_bracket_include = 0;
-/* This is the first element in the chain that corresponds to
- a directory of system header files. */
-static struct file_name_list *first_system_include = 0;
-static struct file_name_list *last_include = 0; /* Last in chain */
-
-/* Chain of include directories to put at the end of the other chain. */
-static struct file_name_list *after_include = 0;
-static struct file_name_list *last_after_include = 0; /* Last in chain */
-
-/* Chain to put at the start of the system include files. */
-static struct file_name_list *before_system = 0;
-static struct file_name_list *last_before_system = 0; /* Last in chain */
-
-/* Directory prefix that should replace `/usr' in the standard
- include file directories. */
-static char *include_prefix;
-
-/* Maintain and search list of included files. */
-
-struct include_file {
- struct include_file *next; /* for include_hashtab */
- struct include_file *next_ino; /* for include_ino_hashtab */
- char *fname;
- /* If the following is the empty string, it means #pragma once
- was seen in this include file, or #import was applied to the file.
- Otherwise, if it is nonzero, it is a macro name.
- Don't include the file again if that macro is defined. */
- const U_CHAR *control_macro;
- /* Nonzero if the dependency on this include file has been output. */
- int deps_output;
- struct stat st;
-};
-
-/* Hash tables of files already included with #include or #import.
- include_hashtab is by full name; include_ino_hashtab is by inode number. */
-
-#define INCLUDE_HASHSIZE 61
-static struct include_file *include_hashtab[INCLUDE_HASHSIZE];
-static struct include_file *include_ino_hashtab[INCLUDE_HASHSIZE];
-
-/* Global list of strings read in from precompiled files. This list
- is kept in the order the strings are read in, with new strings being
- added at the end through stringlist_tailp. We use this list to output
- the strings at the end of the run.
-*/
-static STRINGDEF *stringlist;
-static STRINGDEF **stringlist_tailp = &stringlist;
-
-
-/* Structure returned by create_definition */
-typedef struct macrodef MACRODEF;
-struct macrodef
-{
- struct definition *defn;
- const U_CHAR *symnam;
- int symlen;
-};
-
-enum sharp_token_type {
- NO_SHARP_TOKEN = 0, /* token not present */
-
- SHARP_TOKEN = '#', /* token spelled with # only */
- WHITE_SHARP_TOKEN, /* token spelled with # and white space */
-
- PERCENT_COLON_TOKEN = '%', /* token spelled with %: only */
- WHITE_PERCENT_COLON_TOKEN /* token spelled with %: and white space */
-};
-
-/* Structure allocated for every #define. For a simple replacement
- such as
- #define foo bar ,
- nargs = -1, the `pattern' list is null, and the expansion is just
- the replacement text. Nargs = 0 means a functionlike macro with no args,
- e.g.,
- #define getchar() getc (stdin) .
- When there are args, the expansion is the replacement text with the
- args squashed out, and the reflist is a list describing how to
- build the output from the input: e.g., "3 chars, then the 1st arg,
- then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".
- The chars here come from the expansion. Whatever is left of the
- expansion after the last arg-occurrence is copied after that arg.
- Note that the reflist can be arbitrarily long---
- its length depends on the number of times the arguments appear in
- the replacement text, not how many args there are. Example:
- #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
- pattern list
- { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
- where (x, y) means (nchars, argno). */
-
-typedef struct definition DEFINITION;
-struct definition {
- int nargs;
- int length; /* length of expansion string */
- int predefined; /* True if the macro was builtin or */
- /* came from the command line */
- U_CHAR *expansion;
- int line; /* Line number of definition */
- const char *file; /* File of definition */
- size_t file_len; /* Length of file (which can contain NULs) */
- char rest_args; /* Nonzero if last arg. absorbs the rest */
- struct reflist {
- struct reflist *next;
-
- enum sharp_token_type stringify; /* set if a # operator before arg */
- enum sharp_token_type raw_before; /* set if a ## operator before arg */
- enum sharp_token_type raw_after; /* set if a ## operator after arg */
-
- char rest_args; /* Nonzero if this arg. absorbs the rest */
- int nchars; /* Number of literal chars to copy before
- this arg occurrence. */
- int argno; /* Number of arg to substitute (origin-0) */
- } *pattern;
- union {
- /* Names of macro args, concatenated in reverse order
- with comma-space between them.
- The only use of this is that we warn on redefinition
- if this differs between the old and new definitions. */
- U_CHAR *argnames;
- } args;
-};
-
-/* different kinds of things that can appear in the value field
- of a hash node. Actually, this may be useless now. */
-union hashval {
- const char *cpval;
- DEFINITION *defn;
- KEYDEF *keydef;
-};
-
-/*
- * special extension string that can be added to the last macro argument to
- * allow it to absorb the "rest" of the arguments when expanded. Ex:
- * #define wow(a, b...) process (b, a, b)
- * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); }
- * { wow (one, two); } -> { process (two, one, two); }
- * if this "rest_arg" is used with the concat token '##' and if it is not
- * supplied then the token attached to with ## will not be outputted. Ex:
- * #define wow (a, b...) process (b ## , a, ## b)
- * { wow (1, 2); } -> { process (2, 1, 2); }
- * { wow (one); } -> { process (one); {
- */
-static char rest_extension[] = "...";
-#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
-
-/* This is the implicit parameter name when using variable number of
- parameters for macros using the ISO C 99 extension. */
-static char va_args_name[] = "__VA_ARGS__";
-#define VA_ARGS_NAME_LENGTH (sizeof (va_args_name) - 1)
-
-/* The structure of a node in the hash table. The hash table
- has entries for all tokens defined by #define directives (type T_MACRO),
- plus some special tokens like __LINE__ (these each have their own
- type, and the appropriate code is run when that type of node is seen.
- It does not contain control words like "#define", which are recognized
- by a separate piece of code. */
-
-/* different flavors of hash nodes --- also used in keyword table */
-enum node_type {
- T_DEFINE = 1, /* the `#define' keyword */
- T_INCLUDE, /* the `#include' keyword */
- T_INCLUDE_NEXT, /* the `#include_next' keyword */
- T_IMPORT, /* the `#import' keyword */
- T_IFDEF, /* the `#ifdef' keyword */
- T_IFNDEF, /* the `#ifndef' keyword */
- T_IF, /* the `#if' keyword */
- T_ELSE, /* `#else' */
- T_PRAGMA, /* `#pragma' */
- T_ELIF, /* `#elif' */
- T_UNDEF, /* `#undef' */
- T_LINE, /* `#line' */
- T_ERROR, /* `#error' */
- T_WARNING, /* `#warning' */
- T_ENDIF, /* `#endif' */
- T_SCCS, /* `#sccs', used on system V. */
- T_IDENT, /* `#ident', used on system V. */
- T_ASSERT, /* `#assert', taken from system V. */
- T_UNASSERT, /* `#unassert', taken from system V. */
- T_SPECLINE, /* special symbol `__LINE__' */
- T_DATE, /* `__DATE__' */
- T_FILE, /* `__FILE__' */
- T_BASE_FILE, /* `__BASE_FILE__' */
- T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
- T_VERSION, /* `__VERSION__' */
- T_SIZE_TYPE, /* `__SIZE_TYPE__' */
- T_PTRDIFF_TYPE, /* `__PTRDIFF_TYPE__' */
- T_WCHAR_TYPE, /* `__WCHAR_TYPE__' */
- T_USER_LABEL_PREFIX_TYPE, /* `__USER_LABEL_PREFIX__' */
- T_REGISTER_PREFIX_TYPE, /* `__REGISTER_PREFIX__' */
- T_IMMEDIATE_PREFIX_TYPE, /* `__IMMEDIATE_PREFIX__' */
- T_TIME, /* `__TIME__' */
- T_CONST, /* Constant value, used by `__STDC__' */
- T_MACRO, /* macro defined by `#define' */
- T_DISABLED, /* macro temporarily turned off for rescan */
- T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
- T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */
- T_POISON, /* defined with `#pragma poison' */
- T_UNUSED /* Used for something not defined. */
- };
-
-struct hashnode {
- struct hashnode *next; /* double links for easy deletion */
- struct hashnode *prev;
- struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash
- chain is kept, in case the node is the head
- of the chain and gets deleted. */
- enum node_type type; /* type of special token */
- int length; /* length of token, for quick comparison */
- U_CHAR *name; /* the actual name */
- union hashval value; /* pointer to expansion, or whatever */
-};
-
-typedef struct hashnode HASHNODE;
-
-/* Some definitions for the hash table. The hash function MUST be
- computed as shown in hashf () below. That is because the rescan
- loop computes the hash value `on the fly' for most tokens,
- in order to avoid the overhead of a lot of procedure calls to
- the hashf () function. Hashf () only exists for the sake of
- politeness, for use when speed isn't so important. */
-
-#define HASHSIZE 1403
-static HASHNODE *hashtab[HASHSIZE];
-#define HASHSTEP(old, c) ((old << 2) + c)
-#define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */
-
-
-/* We let tm.h override the types used here, to handle trivial differences
- such as the choice of unsigned int or long unsigned int for size_t.
- When machines start needing nontrivial differences in the size type,
- it would be best to do something here to figure out automatically
- from other information what type to use. */
-
-/* The string value for __SIZE_TYPE__. */
-
-#ifndef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
-#endif
-
-/* The string value for __PTRDIFF_TYPE__. */
-
-#ifndef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
-#endif
-
-/* The string value for __WCHAR_TYPE__. */
-
-#ifndef WCHAR_TYPE
-#define WCHAR_TYPE "int"
-#endif
-static const char * wchar_type = WCHAR_TYPE;
-#undef WCHAR_TYPE
-
-/* The string value for __USER_LABEL_PREFIX__ */
-
-#ifndef USER_LABEL_PREFIX
-#define USER_LABEL_PREFIX ""
-#endif
-static const char * user_label_prefix = USER_LABEL_PREFIX;
-#undef USER_LABEL_PREFIX
-
-/* The string value for __REGISTER_PREFIX__ */
-
-#ifndef REGISTER_PREFIX
-#define REGISTER_PREFIX ""
-#endif
-
-/* The string value for __IMMEDIATE_PREFIX__ */
-
-#ifndef IMMEDIATE_PREFIX
-#define IMMEDIATE_PREFIX ""
-#endif
-
-/* In the definition of a #assert name, this structure forms
- a list of the individual values asserted.
- Each value is itself a list of "tokens".
- These are strings that are compared by name. */
-
-struct tokenlist_list {
- struct tokenlist_list *next;
- struct arglist *tokens;
-};
-
-struct assertion_hashnode {
- struct assertion_hashnode *next; /* double links for easy deletion */
- struct assertion_hashnode *prev;
- /* also, a back pointer to this node's hash
- chain is kept, in case the node is the head
- of the chain and gets deleted. */
- struct assertion_hashnode **bucket_hdr;
- int length; /* length of token, for quick comparison */
- U_CHAR *name; /* the actual name */
- /* List of token-sequences. */
- struct tokenlist_list *value;
-};
-
-typedef struct assertion_hashnode ASSERTION_HASHNODE;
-
-/* Some definitions for the hash table. The hash function MUST be
- computed as shown in hashf below. That is because the rescan
- loop computes the hash value `on the fly' for most tokens,
- in order to avoid the overhead of a lot of procedure calls to
- the hashf function. hashf only exists for the sake of
- politeness, for use when speed isn't so important. */
-
-#define ASSERTION_HASHSIZE 37
-static ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE];
-
-/* Nonzero means inhibit macroexpansion of what seem to be
- assertion tests, in rescan. For #if. */
-static int assertions_flag;
-
-/* `struct directive' defines one #-directive, including how to handle it. */
-
-#define DO_PROTO PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *))
-
-struct directive {
- int length; /* Length of name */
- int (*func) DO_PROTO; /* Function to handle directive */
- const char *name; /* Name of directive */
- enum node_type type; /* Code which describes which directive. */
-};
-
-#define IS_INCLUDE_DIRECTIVE_TYPE(t) \
-((int) T_INCLUDE <= (int) (t) && (int) (t) <= (int) T_IMPORT)
-
-/* These functions are declared to return int instead of void since they
- are going to be placed in the table and some old compilers have trouble with
- pointers to functions returning void. */
-
-static int do_assert DO_PROTO;
-static int do_define DO_PROTO;
-static int do_elif DO_PROTO;
-static int do_else DO_PROTO;
-static int do_endif DO_PROTO;
-static int do_error DO_PROTO;
-static int do_ident DO_PROTO;
-static int do_if DO_PROTO;
-static int do_include DO_PROTO;
-static int do_line DO_PROTO;
-static int do_pragma DO_PROTO;
-#ifdef SCCS_DIRECTIVE
-static int do_sccs DO_PROTO;
-#endif
-static int do_unassert DO_PROTO;
-static int do_undef DO_PROTO;
-static int do_xifdef DO_PROTO;
-
-/* Here is the actual list of #-directives, most-often-used first. */
-
-static struct directive directive_table[] = {
- { 6, do_define, "define", T_DEFINE},
- { 2, do_if, "if", T_IF},
- { 5, do_xifdef, "ifdef", T_IFDEF},
- { 6, do_xifdef, "ifndef", T_IFNDEF},
- { 5, do_endif, "endif", T_ENDIF},
- { 4, do_else, "else", T_ELSE},
- { 4, do_elif, "elif", T_ELIF},
- { 4, do_line, "line", T_LINE},
- { 7, do_include, "include", T_INCLUDE},
- { 12, do_include, "include_next", T_INCLUDE_NEXT},
- { 6, do_include, "import", T_IMPORT},
- { 5, do_undef, "undef", T_UNDEF},
- { 5, do_error, "error", T_ERROR},
- { 7, do_error, "warning", T_WARNING},
-#ifdef SCCS_DIRECTIVE
- { 4, do_sccs, "sccs", T_SCCS},
-#endif
- { 6, do_pragma, "pragma", T_PRAGMA},
- { 5, do_ident, "ident", T_IDENT},
- { 6, do_assert, "assert", T_ASSERT},
- { 8, do_unassert, "unassert", T_UNASSERT},
- { -1, 0, "", T_UNUSED},
-};
-
-/* When a directive handler is called,
- this points to the # (or the : of the %:) that started the directive. */
-U_CHAR *directive_start;
-
-/* table to tell if char can be part of a C identifier. */
-U_CHAR is_idchar[256];
-/* table to tell if char can be first char of a c identifier. */
-U_CHAR is_idstart[256];
-/* table to tell if c is horizontal space. */
-static U_CHAR is_hor_space[256];
-/* table to tell if c is horizontal or vertical space. */
-U_CHAR is_space[256];
-
-#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
-#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
-
-static int errors = 0; /* Error counter for exit code */
-
-/* Name of output file, for error messages. */
-static const char *out_fname;
-
-/* Nonzero to ignore \ in string constants. Use to treat #line 1 "A:\file.h
- as a non-form feed. If you want it to be a form feed, you must use
- # 1 "\f". */
-static int ignore_escape_flag = 1;
-
-/* Stack of conditionals currently in progress
- (including both successful and failing conditionals). */
-
-struct if_stack {
- struct if_stack *next; /* for chaining to the next stack frame */
- const char *fname; /* copied from input when frame is made */
- size_t fname_len; /* similarly */
- int lineno; /* similarly */
- int if_succeeded; /* true if a leg of this if-group
- has been passed through rescan */
- const U_CHAR *control_macro; /* For #ifndef at start of file,
- this is the macro name tested. */
- enum node_type type; /* type of last directive seen in this group */
-};
-typedef struct if_stack IF_STACK_FRAME;
-static IF_STACK_FRAME *if_stack = NULL;
-
-/* Buffer of -M output. */
-static char *deps_buffer;
-
-/* Number of bytes allocated in above. */
-static int deps_allocated_size;
-
-/* Number of bytes used. */
-static int deps_size;
-
-/* Number of bytes since the last newline. */
-static int deps_column;
-
-/* Nonzero means -I- has been seen,
- so don't look for #include "foo" the source-file directory. */
-static int ignore_srcdir;
-
-static int safe_read PARAMS ((int, char *, int));
-static void safe_write PARAMS ((int, const char *, int));
-
-int main PARAMS ((int, char **));
-
-static void path_include PARAMS ((char *));
-
-static const U_CHAR *index0 PARAMS ((const U_CHAR *, int, size_t));
-
-static void trigraph_pcp PARAMS ((FILE_BUF *));
-static void check_white_space PARAMS ((FILE_BUF *));
-
-static void newline_fix PARAMS ((U_CHAR *));
-static void name_newline_fix PARAMS ((U_CHAR *));
-
-static const char *get_lintcmd PARAMS ((const U_CHAR *, const U_CHAR *,
- const U_CHAR **, int *, int *));
-
-static void rescan PARAMS ((FILE_BUF *, int));
-
-static FILE_BUF expand_to_temp_buffer PARAMS ((const U_CHAR *, const U_CHAR *,
- int, int));
-
-static int handle_directive PARAMS ((FILE_BUF *, FILE_BUF *));
-
-static struct tm *timestamp PARAMS ((void));
-static void special_symbol PARAMS ((HASHNODE *, FILE_BUF *));
-
-static int is_system_include PARAMS ((const char *));
-static char *base_name PARAMS ((const char *));
-static int absolute_filename PARAMS ((const char *));
-static size_t simplify_filename PARAMS ((char *));
-
-static char *read_filename_string PARAMS ((int, FILE *));
-static struct file_name_map *read_name_map PARAMS ((const char *));
-static int open_include_file PARAMS ((char *, struct file_name_list *,
- const U_CHAR *, struct include_file **));
-static char *remap_include_file PARAMS ((char *, struct file_name_list *));
-static int lookup_ino_include PARAMS ((struct include_file *));
-
-static void finclude PARAMS ((int, struct include_file *, FILE_BUF *, int,
- struct file_name_list *));
-static void record_control_macro PARAMS ((struct include_file *,
- const U_CHAR *));
-
-static char *check_precompiled PARAMS ((int, struct stat *, const char *,
- const char **));
-static int check_preconditions PARAMS ((const char *));
-static void pcfinclude PARAMS ((U_CHAR *, const U_CHAR *, FILE_BUF *));
-static void pcstring_used PARAMS ((HASHNODE *));
-static void write_output PARAMS ((void));
-static void pass_thru_directive PARAMS ((const U_CHAR *, const U_CHAR *,
- FILE_BUF *, struct directive *));
-
-static MACRODEF create_definition PARAMS ((const U_CHAR *, const U_CHAR *,
- FILE_BUF *));
-
-static int check_macro_name PARAMS ((const U_CHAR *, int));
-static int compare_defs PARAMS ((DEFINITION *, DEFINITION *));
-static int comp_def_part PARAMS ((int, const U_CHAR *, int, const U_CHAR *,
- int, int));
-
-static DEFINITION *collect_expansion PARAMS ((const U_CHAR *, const U_CHAR *,
- int, struct arglist *));
-
-int check_assertion PARAMS ((const U_CHAR *, int, int, struct arglist *));
-static int compare_token_lists PARAMS ((struct arglist *, struct arglist *));
-
-static struct arglist *read_token_list PARAMS ((const U_CHAR **,
- const U_CHAR *, int *));
-static void free_token_list PARAMS ((struct arglist *));
-
-static ASSERTION_HASHNODE *assertion_install PARAMS ((const U_CHAR *, int, int));
-static ASSERTION_HASHNODE *assertion_lookup PARAMS ((const U_CHAR *, int, int));
-static void delete_assertion PARAMS ((ASSERTION_HASHNODE *));
-
-static void do_once PARAMS ((void));
-
-static HOST_WIDEST_INT eval_if_expression PARAMS ((const U_CHAR *, int));
-static void conditional_skip PARAMS ((FILE_BUF *, int, enum node_type,
- const U_CHAR *, FILE_BUF *));
-static void skip_if_group PARAMS ((FILE_BUF *, int, FILE_BUF *));
-static void validate_else PARAMS ((const U_CHAR *, const U_CHAR *));
-
-static U_CHAR *skip_to_end_of_comment PARAMS ((FILE_BUF *, int *, int));
-static U_CHAR *skip_quoted_string PARAMS ((const U_CHAR *, const U_CHAR *,
- int, int *, int *, int *));
-static char *quote_string PARAMS ((char *, const char *, size_t));
-static U_CHAR *skip_paren_group PARAMS ((FILE_BUF *));
-
-/* Last arg to output_line_directive. */
-enum file_change_code {same_file, enter_file, leave_file};
-static void output_line_directive PARAMS ((FILE_BUF *, FILE_BUF *, int, enum file_change_code));
-
-static void macroexpand PARAMS ((HASHNODE *, FILE_BUF *));
-
-struct argdata;
-static int macarg PARAMS ((struct argdata *, int));
-
-static U_CHAR *macarg1 PARAMS ((U_CHAR *, const U_CHAR *, struct hashnode *, int *, int *, int *, int));
-
-static int discard_comments PARAMS ((U_CHAR *, int, int));
-
-static void change_newlines PARAMS ((struct argdata *));
-
-static void notice PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-static void vnotice PARAMS ((const char *, va_list));
-void error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void verror PARAMS ((const char *, va_list));
-static void error_from_errno PARAMS ((const char *));
-void warning PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-static void vwarning PARAMS ((const char *, va_list));
-static void error_with_line PARAMS ((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
-static void verror_with_line PARAMS ((int, const char *, va_list));
-static void vwarning_with_line PARAMS ((int, const char *, va_list));
-static void warning_with_line PARAMS ((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
-void pedwarn PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void pedwarn_with_line PARAMS ((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
-static void pedwarn_with_file_and_line PARAMS ((const char *, size_t, int, const char *, ...)) ATTRIBUTE_PRINTF_4;
-static void pedwarn_strange_white_space PARAMS ((int));
-
-static void print_containing_files PARAMS ((void));
-
-static int line_for_error PARAMS ((int));
-static int grow_outbuf PARAMS ((FILE_BUF *, int));
-
-static HASHNODE *install PARAMS ((const U_CHAR *, int, enum node_type,
- const char *, int));
-HASHNODE *lookup PARAMS ((const U_CHAR *, int, int));
-static void delete_macro PARAMS ((HASHNODE *));
-static int hashf PARAMS ((const U_CHAR *, int, int));
-
-static void dump_single_macro PARAMS ((HASHNODE *, FILE *));
-static void dump_all_macros PARAMS ((void));
-static void dump_defn_1 PARAMS ((const U_CHAR *, int, int, FILE *));
-static void dump_arg_n PARAMS ((DEFINITION *, int, FILE *));
-
-static void initialize_char_syntax PARAMS ((void));
-static void initialize_builtins PARAMS ((FILE_BUF *, FILE_BUF *));
-
-static void make_definition PARAMS ((char *));
-static void make_undef PARAMS ((char *, FILE_BUF *));
-
-static void make_assertion PARAMS ((const char *, const char *));
-
-static struct file_name_list *new_include_prefix PARAMS ((struct file_name_list *, const char *, const char *, const char *));
-static void append_include_chain PARAMS ((struct file_name_list *, struct file_name_list *));
-
-static int quote_string_for_make PARAMS ((char *, const char *));
-static void deps_output PARAMS ((const char *, int));
-
-void fatal PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
-static void perror_with_name PARAMS ((const char *));
-static void pfatal_with_name PARAMS ((const char *)) ATTRIBUTE_NORETURN;
-static void pipe_closed PARAMS ((int)) ATTRIBUTE_NORETURN;
-
-static void memory_full PARAMS ((void)) ATTRIBUTE_NORETURN;
-static void print_help PARAMS ((void));
-
-/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
- retrying if necessary. If MAX_READ_LEN is defined, read at most
- that bytes at a time. Return a negative value if an error occurs,
- otherwise return the actual number of bytes read,
- which must be LEN unless end-of-file was reached. */
-
-static int
-safe_read (desc, ptr, len)
- int desc;
- char *ptr;
- int len;
-{
- int left, rcount, nchars;
-
- left = len;
- while (left > 0) {
- rcount = left;
-#ifdef MAX_READ_LEN
- if (rcount > MAX_READ_LEN)
- rcount = MAX_READ_LEN;
-#endif
- nchars = read (desc, ptr, rcount);
- if (nchars < 0)
- {
-#ifdef EINTR
- if (errno == EINTR)
- continue;
-#endif
- return nchars;
- }
- if (nchars == 0)
- break;
- ptr += nchars;
- left -= nchars;
- }
- return len - left;
-}
-
-/* Write LEN bytes at PTR to descriptor DESC,
- retrying if necessary, and treating any real error as fatal.
- If MAX_WRITE_LEN is defined, write at most that many bytes at a time. */
-
-static void
-safe_write (desc, ptr, len)
- int desc;
- const char *ptr;
- int len;
-{
- int wcount, written;
-
- while (len > 0) {
- wcount = len;
-#ifdef MAX_WRITE_LEN
- if (wcount > MAX_WRITE_LEN)
- wcount = MAX_WRITE_LEN;
-#endif
- written = write (desc, ptr, wcount);
- if (written < 0)
- {
-#ifdef EINTR
- if (errno == EINTR)
- continue;
-#endif
- pfatal_with_name (out_fname);
- }
- ptr += written;
- len -= written;
- }
-}
-
-
-static void
-print_help ()
-{
- printf ("Usage: %s [switches] input output\n", progname);
- printf ("Switches:\n");
- printf (" -include <file> Include the contents of <file> before other files\n");
- printf (" -imacros <file> Accept definition of macros in <file>\n");
- printf (" -iprefix <path> Specify <path> as a prefix for next two options\n");
- printf (" -iwithprefix <dir> Add <dir> to the end of the system include paths\n");
- printf (" -iwithprefixbefore <dir> Add <dir> to the end of the main include paths\n");
- printf (" -isystem <dir> Add <dir> to the start of the system include paths\n");
- printf (" -idirafter <dir> Add <dir> to the end of the system include paths\n");
- printf (" -I <dir> Add <dir> to the end of the main include paths\n");
- printf (" -nostdinc Do not search the system include directories\n");
- printf (" -nostdinc++ Do not search the system include directories for C++\n");
- printf (" -o <file> Put output into <file>\n");
- printf (" -pedantic Issue all warnings demanded by strict ANSI C\n");
- printf (" -traditional Follow K&R pre-processor behaviour\n");
- printf (" -trigraphs Support ANSI C trigraphs\n");
- printf (" -lang-c Assume that the input sources are in C\n");
- printf (" -lang-c89 Assume that the input is C89; depricated\n");
- printf (" -lang-c++ Assume that the input sources are in C++\n");
- printf (" -lang-objc Assume that the input sources are in ObjectiveC\n");
- printf (" -lang-objc++ Assume that the input sources are in ObjectiveC++\n");
- printf (" -lang-asm Assume that the input sources are in assembler\n");
- printf (" -lang-fortran Assume that the input sources are in Fortran\n");
- printf (" -lang-chill Assume that the input sources are in Chill\n");
- printf (" -std=<std name> Specify the conformance standard; one of:\n");
- printf (" gnu89, gnu99, c89, c99, iso9899:1990,\n");
- printf (" iso9899:199409, iso9899:1999\n");
- printf (" -+ Allow parsing of C++ style features\n");
- printf (" -w Inhibit warning messages\n");
- printf (" -Wtrigraphs Warn if trigraphs are encountered\n");
- printf (" -Wno-trigraphs Do not warn about trigraphs\n");
- printf (" -Wcomment{s} Warn if one comment starts inside another\n");
- printf (" -Wno-comment{s} Do not warn about comments\n");
- printf (" -Wtraditional Warn if a macro argument is/would be turned into\n");
- printf (" a string if -traditional is specified\n");
- printf (" -Wno-traditional Do not warn about stringification\n");
- printf (" -Wundef Warn if an undefined macro is used by #if\n");
- printf (" -Wno-undef Do not warn about testing undefined macros\n");
- printf (" -Wimport Warn about the use of the #import directive\n");
- printf (" -Wno-import Do not warn about the use of #import\n");
- printf (" -Werror Treat all warnings as errors\n");
- printf (" -Wno-error Do not treat warnings as errors\n");
- printf (" -Wall Enable all preprocessor warnings\n");
- printf (" -M Generate make dependencies\n");
- printf (" -MM As -M, but ignore system header files\n");
- printf (" -MD As -M, but put output in a .d file\n");
- printf (" -MMD As -MD, but ignore system header files\n");
- printf (" -MG Treat missing header file as generated files\n");
- printf (" -g Include #define and #undef directives in the output\n");
- printf (" -D<macro> Define a <macro> with string '1' as its value\n");
- printf (" -D<macro>=<val> Define a <macro> with <val> as its value\n");
- printf (" -A<question> (<answer>) Assert the <answer> to <question>\n");
- printf (" -U<macro> Undefine <macro> \n");
- printf (" -u or -undef Do not predefine any macros\n");
- printf (" -v Display the version number\n");
- printf (" -H Print the name of header files as they are used\n");
- printf (" -C Do not discard comments\n");
- printf (" -dM Display a list of macro definitions active at end\n");
- printf (" -dD Preserve macro definitions in output\n");
- printf (" -dN As -dD except that only the names are preserved\n");
- printf (" -dI Include #include directives in the output\n");
- printf (" -ifoutput Describe skipped code blocks in output \n");
- printf (" -P Do not generate #line directives\n");
- printf (" -$ Do not include '$' in identifiers\n");
- printf (" -remap Remap file names when including files.\n");
- printf (" -h or --help Display this information\n");
-}
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- struct stat st;
- const char *in_fname;
- char *cp;
- int f, i;
- FILE_BUF *fp;
-
- char **pend_files;
- char **pend_defs;
- char **pend_undefs;
- char **pend_assertions;
- char **pend_includes;
-
- /* Record the option used with each element of pend_assertions.
- This is preparation for supporting more than one option for making
- an assertion. */
- const char **pend_assertion_options;
- int no_standard_includes = 0;
- int no_standard_cplusplus_includes = 0;
- int missing_newline = 0;
-
- /* Non-0 means don't output the preprocessed program. */
- int inhibit_output = 0;
- /* Non-0 means -v, so print the full set of include dirs. */
- int verbose = 0;
-
- /* File name which deps are being written to.
- This is 0 if deps are being written to stdout. */
- char *deps_file = 0;
- /* Fopen file mode to open deps_file with. */
- const char *deps_mode = "a";
- /* Stream on which to print the dependency information. */
- FILE *deps_stream = 0;
- /* Target-name to write with the dependency information. */
- char *deps_target = 0;
-
-#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
- /* Get rid of any avoidable limit on stack size. */
- {
- struct rlimit rlim;
-
- /* Set the stack limit huge so that alloca (particularly stringtab
- in dbxread.c) does not fail. */
- getrlimit (RLIMIT_STACK, &rlim);
- rlim.rlim_cur = rlim.rlim_max;
- setrlimit (RLIMIT_STACK, &rlim);
- }
-#endif
-
-#ifdef SIGPIPE
- signal (SIGPIPE, pipe_closed);
-#endif
-
-#ifdef HAVE_LC_MESSAGES
- setlocale (LC_MESSAGES, "");
-#endif
- (void) bindtextdomain (PACKAGE, localedir);
- (void) textdomain (PACKAGE);
-
- progname = base_name (argv[0]);
-
-#ifdef VMS
- {
- /* Remove extension from PROGNAME. */
- char *p;
- char *s = xstrdup (progname);
- progname = s;
-
- if ((p = rindex (s, ';')) != 0) *p = '\0'; /* strip version number */
- if ((p = rindex (s, '.')) != 0 /* strip type iff ".exe" */
- && (p[1] == 'e' || p[1] == 'E')
- && (p[2] == 'x' || p[2] == 'X')
- && (p[3] == 'e' || p[3] == 'E')
- && !p[4])
- *p = '\0';
- }
-#endif
-
- /* Do not invoke xmalloc before this point, since locale and
- progname need to be set first, in case a diagnostic is issued. */
-
- pend_files = (char **) xmalloc (argc * sizeof (char *));
- pend_defs = (char **) xmalloc ((2 * argc) * sizeof (char *));
- pend_undefs = (char **) xmalloc (argc * sizeof (char *));
- pend_assertions = (char **) xmalloc (argc * sizeof (char *));
- pend_includes = (char **) xmalloc (argc * sizeof (char *));
- pend_assertion_options = (const char **) xmalloc (argc * sizeof (char *));
-
- in_fname = NULL;
- out_fname = NULL;
-
- /* Initialize is_idchar. */
- initialize_char_syntax ();
-
- no_line_directives = 0;
- no_trigraphs = 1;
- dump_macros = dump_none;
- no_output = 0;
- cplusplus = 0;
- cplusplus_comments = 1;
-
- bzero ((char *) pend_files, argc * sizeof (char *));
- bzero ((char *) pend_defs, (2 * argc) * sizeof (char *));
- bzero ((char *) pend_undefs, argc * sizeof (char *));
- bzero ((char *) pend_assertions, argc * sizeof (char *));
- bzero ((char *) pend_includes, argc * sizeof (char *));
-
-#ifdef MULTIBYTE_CHARS
- /* Change to the native locale for multibyte conversions. */
- setlocale (LC_CTYPE, "");
- literal_codeset = getenv ("LANG");
-#endif
-
- /* Process switches and find input file name. */
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] != '-') {
- if (out_fname != NULL)
- {
- print_help ();
- fatal ("Too many arguments");
- }
- else if (in_fname != NULL)
- out_fname = argv[i];
- else
- in_fname = argv[i];
- } else {
- switch (argv[i][1]) {
-
- case 'i':
- if (!strcmp (argv[i], "-include")) {
- if (i + 1 == argc)
- fatal ("Filename missing after `-include' option");
- else {
- i++;
- simplify_filename (pend_includes[i] = argv[i]);
- }
- }
- if (!strcmp (argv[i], "-imacros")) {
- if (i + 1 == argc)
- fatal ("Filename missing after `-imacros' option");
- else {
- i++;
- simplify_filename (pend_files[i] = argv[i]);
- }
- }
- if (!strcmp (argv[i], "-iprefix")) {
- if (i + 1 == argc)
- fatal ("Filename missing after `-iprefix' option");
- else
- include_prefix = argv[++i];
- }
- if (!strcmp (argv[i], "-ifoutput")) {
- output_conditionals = 1;
- }
- if (!strcmp (argv[i], "-isystem")) {
- struct file_name_list *dirtmp;
-
- if (! (dirtmp = new_include_prefix (NULL_PTR, NULL_PTR,
- "", argv[++i])))
- break;
- dirtmp->c_system_include_path = 1;
-
- if (before_system == 0)
- before_system = dirtmp;
- else
- last_before_system->next = dirtmp;
- last_before_system = dirtmp; /* Tail follows the last one */
- }
- /* Add directory to end of path for includes,
- with the default prefix at the front of its name. */
- if (!strcmp (argv[i], "-iwithprefix")) {
- struct file_name_list *dirtmp;
- char *prefix;
-
- if (include_prefix != 0)
- prefix = include_prefix;
- else {
- prefix = xstrdup (GCC_INCLUDE_DIR);
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
- prefix[strlen (prefix) - 7] = 0;
- }
-
- if (! (dirtmp = new_include_prefix (NULL_PTR, NULL_PTR,
- prefix, argv[++i])))
- break;
-
- if (after_include == 0)
- after_include = dirtmp;
- else
- last_after_include->next = dirtmp;
- last_after_include = dirtmp; /* Tail follows the last one */
- }
- /* Add directory to main path for includes,
- with the default prefix at the front of its name. */
- if (!strcmp (argv[i], "-iwithprefixbefore")) {
- struct file_name_list *dirtmp;
- char *prefix;
-
- if (include_prefix != 0)
- prefix = include_prefix;
- else {
- prefix = xstrdup (GCC_INCLUDE_DIR);
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (!strcmp (prefix + strlen (prefix) - 8, "/include"))
- prefix[strlen (prefix) - 7] = 0;
- }
-
- dirtmp = new_include_prefix (NULL_PTR, NULL_PTR, prefix, argv[++i]);
- append_include_chain (dirtmp, dirtmp);
- }
- /* Add directory to end of path for includes. */
- if (!strcmp (argv[i], "-idirafter")) {
- struct file_name_list *dirtmp;
-
- if (! (dirtmp = new_include_prefix (NULL_PTR, NULL_PTR,
- "", argv[++i])))
- break;
-
- if (after_include == 0)
- after_include = dirtmp;
- else
- last_after_include->next = dirtmp;
- last_after_include = dirtmp; /* Tail follows the last one */
- }
- break;
-
- case 'o':
- if (out_fname != NULL)
- fatal ("Output filename specified twice");
- if (i + 1 == argc)
- fatal ("Filename missing after -o option");
- out_fname = argv[++i];
- if (!strcmp (out_fname, "-"))
- out_fname = "";
- break;
-
- case 'p':
- if (!strcmp (argv[i], "-pedantic"))
- pedantic = 1;
- else if (!strcmp (argv[i], "-pedantic-errors")) {
- pedantic = 1;
- pedantic_errors = 1;
- } else if (!strcmp (argv[i], "-pcp")) {
- char *pcp_fname;
- if (i + 1 == argc)
- fatal ("Filename missing after -pcp option");
- pcp_fname = argv[++i];
- pcp_outfile
- = ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
- ? fopen (pcp_fname, "w")
- : stdout);
- if (pcp_outfile == 0)
- pfatal_with_name (pcp_fname);
- no_precomp = 1;
- }
- break;
-
- case 't':
- if (!strcmp (argv[i], "-traditional")) {
- traditional = 1;
- cplusplus_comments = 0;
- } else if (!strcmp (argv[i], "-trigraphs")) {
- no_trigraphs = 0;
- }
- break;
-
- case 'l':
- if (! strcmp (argv[i], "-lang-c"))
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, c99 = 1, objc = 0;
- else if (! strcmp (argv[i], "-lang-c89"))
- {
- cplusplus = 0, cplusplus_comments = 0, c89 = 1, c99 = 0, objc = 0;
- no_trigraphs = 0;
- pend_defs[2*i] = "__STRICT_ANSI__";
- }
- else if (! strcmp (argv[i], "-lang-c++"))
- cplusplus = 1, cplusplus_comments = 1, c89 = 0, c99 = 0, objc = 0;
- else if (! strcmp (argv[i], "-lang-objc"))
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, c99 = 0, objc = 1;
- else if (! strcmp (argv[i], "-lang-objc++"))
- cplusplus = 1, cplusplus_comments = 1, c89 = 0, c99 = 0, objc = 1;
- else if (! strcmp (argv[i], "-lang-asm"))
- lang_asm = 1;
- else if (! strcmp (argv[i], "-lang-fortran"))
- /* Doesn't actually do anything. */ ;
- else if (! strcmp (argv[i], "-lint"))
- for_lint = 1;
- break;
-
- case '+':
- cplusplus = 1, cplusplus_comments = 1;
- break;
-
- case 's':
- if (!strcmp (argv[i], "-std=gnu89"))
- {
- cplusplus = 0, cplusplus_comments = 0, c89 = 1, c99 = 0, objc = 0;
- }
- else if (!strcmp (argv[i], "-std=gnu9x")
- || !strcmp (argv[i], "-std=gnu99"))
- {
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, c99 = 1, objc = 0;
- pend_defs[2*i+1] = "__STDC_VERSION__=199901L";
- }
- else if (!strcmp (argv[i], "-std=iso9899:1990")
- || !strcmp (argv[i], "-std=c89"))
- {
- cplusplus = 0, cplusplus_comments = 0, c89 = 1, c99 = 0, objc = 0;
- no_trigraphs = 0;
- pend_defs[2*i] = "__STRICT_ANSI__";
- }
- else if (!strcmp (argv[i], "-std=iso9899:199409"))
- {
- cplusplus = 0, cplusplus_comments = 0, c89 = 1, c99 = 0, objc = 0;
- no_trigraphs = 0;
- pend_defs[2*i] = "__STRICT_ANSI__";
- pend_defs[2*i+1] = "__STDC_VERSION__=199409L";
- }
- else if (!strcmp (argv[i], "-std=iso9899:199x")
- || !strcmp (argv[i], "-std=iso9899:1999")
- || !strcmp (argv[i], "-std=c9x")
- || !strcmp (argv[i], "-std=c99"))
- {
- cplusplus = 0, cplusplus_comments = 1, c89 = 0, c99 = 1, objc = 0;
- no_trigraphs = 0;
- pend_defs[2*i] = "__STRICT_ANSI__";
- pend_defs[2*i+1] = "__STDC_VERSION__=199901L";
- }
- break;
-
- case 'w':
- inhibit_warnings = 1;
- break;
-
- case 'W':
- if (!strcmp (argv[i], "-Wtrigraphs"))
- warn_trigraphs = 1;
- else if (!strcmp (argv[i], "-Wno-trigraphs"))
- warn_trigraphs = 0;
- else if (!strcmp (argv[i], "-Wcomment"))
- warn_comments = 1;
- else if (!strcmp (argv[i], "-Wno-comment"))
- warn_comments = 0;
- else if (!strcmp (argv[i], "-Wcomments"))
- warn_comments = 1;
- else if (!strcmp (argv[i], "-Wno-comments"))
- warn_comments = 0;
- else if (!strcmp (argv[i], "-Wtraditional"))
- warn_stringify = 1;
- else if (!strcmp (argv[i], "-Wno-traditional"))
- warn_stringify = 0;
- else if (!strcmp (argv[i], "-Wwhite-space"))
- warn_white_space = 1;
- else if (!strcmp (argv[i], "-Wno-white-space"))
- warn_white_space = 0;
- else if (!strcmp (argv[i], "-Wundef"))
- warn_undef = 1;
- else if (!strcmp (argv[i], "-Wno-undef"))
- warn_undef = 0;
- else if (!strcmp (argv[i], "-Wimport"))
- warn_import = 1;
- else if (!strcmp (argv[i], "-Wno-import"))
- warn_import = 0;
- else if (!strcmp (argv[i], "-Werror"))
- warnings_are_errors = 1;
- else if (!strcmp (argv[i], "-Wno-error"))
- warnings_are_errors = 0;
- else if (!strcmp (argv[i], "-Wall"))
- {
- warn_trigraphs = 1;
- warn_comments = 1;
- warn_white_space = 1;
- }
- break;
-
- case 'f':
- if (!strcmp (argv[i], "-fleading-underscore"))
- user_label_prefix = "_";
- else if (!strcmp (argv[i], "-fno-leading-underscore"))
- user_label_prefix = "";
- break;
-
- case 'M':
- /* The style of the choices here is a bit mixed.
- The chosen scheme is a hybrid of keeping all options in one string
- and specifying each option in a separate argument:
- -M|-MM|-MD file|-MMD file [-MG]. An alternative is:
- -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely:
- -M[M][G][D file]. This is awkward to handle in specs, and is not
- as extensible. */
- /* ??? -MG must be specified in addition to one of -M or -MM.
- This can be relaxed in the future without breaking anything.
- The converse isn't true. */
-
- /* -MG isn't valid with -MD or -MMD. This is checked for later. */
- if (!strcmp (argv[i], "-MG"))
- {
- print_deps_missing_files = 1;
- break;
- }
- if (!strcmp (argv[i], "-M"))
- print_deps = 2;
- else if (!strcmp (argv[i], "-MM"))
- print_deps = 1;
- else if (!strcmp (argv[i], "-MD"))
- print_deps = 2;
- else if (!strcmp (argv[i], "-MMD"))
- print_deps = 1;
- /* For -MD and -MMD options, write deps on file named by next arg. */
- if (!strcmp (argv[i], "-MD")
- || !strcmp (argv[i], "-MMD")) {
- if (i + 1 == argc)
- fatal ("Filename missing after %s option", argv[i]);
- i++;
- deps_file = argv[i];
- deps_mode = "w";
- } else {
- /* For -M and -MM, write deps on standard output
- and suppress the usual output. */
- deps_stream = stdout;
- inhibit_output = 1;
- }
- break;
-
- case 'd':
- {
- char *p = argv[i] + 2;
- char c;
- while ((c = *p++)) {
- /* Arg to -d specifies what parts of macros to dump */
- switch (c) {
- case 'M':
- dump_macros = dump_only;
- no_output = 1;
- break;
- case 'N':
- dump_macros = dump_names;
- break;
- case 'D':
- dump_macros = dump_definitions;
- break;
- case 'I':
- dump_includes = 1;
- break;
- }
- }
- }
- break;
-
- case 'g':
- if (argv[i][2] == '3')
- debug_output = 1;
- break;
-
- case '-':
- if (strcmp (argv[i], "--help") != 0)
- return i;
- print_help ();
- exit (0);
- break;
-
- case 'v':
- notice ("GNU CPP version %s", version_string);
-#ifdef TARGET_VERSION
- TARGET_VERSION;
-#endif
- fprintf (stderr, "\n");
- verbose = 1;
- break;
-
- case 'H':
- print_include_names = 1;
- break;
-
- case 'D':
- if (argv[i][2] != 0)
- pend_defs[2*i] = argv[i] + 2;
- else if (i + 1 == argc)
- fatal ("Macro name missing after -D option");
- else
- i++, pend_defs[2*i] = argv[i];
- break;
-
- case 'A':
- {
- char *p;
-
- if (argv[i][2] != 0)
- p = argv[i] + 2;
- else if (i + 1 == argc)
- fatal ("Assertion missing after -A option");
- else
- p = argv[++i];
-
- if (!strcmp (p, "-")) {
- /* -A- eliminates all predefined macros and assertions.
- Let's include also any that were specified earlier
- on the command line. That way we can get rid of any
- that were passed automatically in from GCC. */
- int j;
- for (j = 0; j < i; j++)
- pend_defs[2*j] = pend_assertions[j] = 0;
- } else {
- pend_assertions[i] = p;
- pend_assertion_options[i] = "-A";
- }
- }
- break;
-
- case 'U': /* JF #undef something */
- if (argv[i][2] != 0)
- pend_undefs[i] = argv[i] + 2;
- else if (i + 1 == argc)
- fatal ("Macro name missing after -U option");
- else
- pend_undefs[i] = argv[i+1], i++;
- break;
-
- case 'C':
- put_out_comments = 1;
- break;
-
- case 'E': /* -E comes from cc -E; ignore it. */
- break;
-
- case 'P':
- no_line_directives = 1;
- break;
-
- case '$': /* Don't include $ in identifiers. */
- is_idchar['$'] = is_idstart['$'] = 0;
- break;
-
- case 'I': /* Add directory to path for includes. */
- {
- struct file_name_list *dirtmp;
- char *dir = argv[i][2] ? argv[i] + 2 : argv[++i];
-
- if (! ignore_srcdir && dir && !strcmp (dir, "-")) {
- ignore_srcdir = 1;
- /* Don't use any preceding -I directories for #include <...>. */
- first_bracket_include = 0;
- }
- else {
- dirtmp = new_include_prefix (last_include, NULL_PTR, "", dir);
- append_include_chain (dirtmp, dirtmp);
- }
- }
- break;
-
- case 'n':
- if (!strcmp (argv[i], "-nostdinc"))
- /* -nostdinc causes no default include directories.
- You must specify all include-file directories with -I. */
- no_standard_includes = 1;
- else if (!strcmp (argv[i], "-nostdinc++"))
- /* -nostdinc++ causes no default C++-specific include directories. */
- no_standard_cplusplus_includes = 1;
- else if (!strcmp (argv[i], "-noprecomp"))
- no_precomp = 1;
- break;
-
- case 'r':
- if (!strcmp (argv[i], "-remap"))
- remap = 1;
- break;
-
- case '\0': /* JF handle '-' as file name meaning stdin or stdout */
- if (in_fname == NULL) {
- in_fname = "";
- break;
- } else if (out_fname == NULL) {
- out_fname = "";
- break;
- } /* else fall through into error */
-
- default:
- fatal ("Invalid option `%s'", argv[i]);
- }
- }
- }
-
- /* Add dirs from CPATH after dirs from -I. */
- /* There seems to be confusion about what CPATH should do,
- so for the moment it is not documented. */
- /* Some people say that CPATH should replace the standard include dirs,
- but that seems pointless: it comes before them, so it overrides them
- anyway. */
- GET_ENV_PATH_LIST (cp, "CPATH");
- if (cp && ! no_standard_includes)
- path_include (cp);
-
- /* Initialize output buffer */
-
- outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE);
- outbuf.bufp = outbuf.buf;
- outbuf.length = OUTBUF_SIZE;
-
- /* Do partial setup of input buffer for the sake of generating
- early #line directives (when -g is in effect). */
-
- fp = &instack[++indepth];
- if (in_fname == NULL)
- in_fname = "";
- fp->nominal_fname = fp->fname = in_fname;
- fp->nominal_fname_len = strlen (in_fname);
- fp->lineno = 0;
-
- /* Install __LINE__, etc. Must follow initialize_char_syntax
- and option processing. */
- initialize_builtins (fp, &outbuf);
-
- /* Now handle the command line options. */
-
- /* Do -U's, -D's and -A's in the order they were seen. */
- for (i = 1; i < argc; i++) {
- if (pend_undefs[i]) {
- if (debug_output)
- output_line_directive (fp, &outbuf, 0, same_file);
- make_undef (pend_undefs[i], &outbuf);
- }
- if (pend_defs[2*i]) {
- if (debug_output)
- output_line_directive (fp, &outbuf, 0, same_file);
- make_definition (pend_defs[2*i]);
- }
- if (pend_defs[2*i+1]) {
- if (debug_output)
- output_line_directive (fp, &outbuf, 0, same_file);
- make_definition (pend_defs[2*i+1]);
- }
- if (pend_assertions[i])
- make_assertion (pend_assertion_options[i], pend_assertions[i]);
- }
-
- done_initializing = 1;
-
- { /* Read the appropriate environment variable and if it exists
- replace include_defaults with the listed path. */
- char *epath = 0;
- switch ((objc << 1) + cplusplus)
- {
- case 0:
- GET_ENV_PATH_LIST (epath, "C_INCLUDE_PATH");
- break;
- case 1:
- GET_ENV_PATH_LIST (epath, "CPLUS_INCLUDE_PATH");
- break;
- case 2:
- GET_ENV_PATH_LIST (epath, "OBJC_INCLUDE_PATH");
- break;
- case 3:
- GET_ENV_PATH_LIST (epath, "OBJCPLUS_INCLUDE_PATH");
- break;
- }
- /* If the environment var for this language is set,
- add to the default list of include directories. */
- if (epath) {
- int num_dirs;
- char *startp, *endp;
-
- for (num_dirs = 1, startp = epath; *startp; startp++)
- if (*startp == PATH_SEPARATOR)
- num_dirs++;
- include_defaults
- = (struct default_include *) xmalloc ((num_dirs
- * sizeof (struct default_include))
- + sizeof (include_defaults_array));
- startp = endp = epath;
- num_dirs = 0;
- while (1) {
- char c = *endp++;
- if (c == PATH_SEPARATOR || !c) {
- endp[-1] = 0;
- include_defaults[num_dirs].fname
- = startp == endp ? "." : xstrdup (startp);
- endp[-1] = c;
- include_defaults[num_dirs].component = 0;
- include_defaults[num_dirs].cplusplus = cplusplus;
- include_defaults[num_dirs].cxx_aware = 1;
- num_dirs++;
- if (!c)
- break;
- startp = endp;
- }
- }
- /* Put the usual defaults back in at the end. */
- bcopy ((const PTR) include_defaults_array,
- (PTR) &include_defaults[num_dirs],
- sizeof (include_defaults_array));
- }
- }
-
- append_include_chain (before_system, last_before_system);
- first_system_include = before_system;
-
- /* Unless -fnostdinc,
- tack on the standard include file dirs to the specified list */
- if (!no_standard_includes) {
- struct default_include *p = include_defaults;
- char *specd_prefix = include_prefix;
- char *default_prefix = xstrdup (GCC_INCLUDE_DIR);
- int default_len = 0;
- /* Remove the `include' from /usr/local/lib/gcc.../include. */
- if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
- default_len = strlen (default_prefix) - 7;
- default_prefix[default_len] = 0;
- }
- /* Search "translated" versions of GNU directories.
- These have /usr/local/lib/gcc... replaced by specd_prefix. */
- if (specd_prefix != 0 && default_len != 0)
- for (p = include_defaults; p->fname; p++) {
- /* Some standard dirs are only for C++. */
- if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {
- /* Does this dir start with the prefix? */
- if (!strncmp (p->fname, default_prefix, default_len)) {
- /* Yes; change prefix and add to search list. */
- struct file_name_list *new
- = new_include_prefix (NULL_PTR, NULL_PTR, specd_prefix,
- p->fname + default_len);
- if (new) {
- new->c_system_include_path = !p->cxx_aware;
- append_include_chain (new, new);
- if (first_system_include == 0)
- first_system_include = new;
- p->included = 1;
- }
- }
- }
- }
- /* Search ordinary names for GNU include directories. */
- for (p = include_defaults; p->fname; p++) {
- /* Some standard dirs are only for C++. */
- if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {
- struct file_name_list *new
- = new_include_prefix (NULL_PTR, p->component, "", p->fname);
- if (new) {
- new->c_system_include_path = !p->cxx_aware;
- append_include_chain (new, new);
- if (first_system_include == 0)
- first_system_include = new;
- p->included = 1;
- }
- }
- }
- }
-
- /* Tack the after_include chain at the end of the include chain. */
- append_include_chain (after_include, last_after_include);
- if (first_system_include == 0)
- first_system_include = after_include;
-
- /* With -v, print the list of dirs to search. */
- if (verbose) {
- struct file_name_list *p;
- notice ("#include \"...\" search starts here:\n");
- for (p = include; p; p = p->next) {
- if (p == first_bracket_include)
- notice ("#include <...> search starts here:\n");
- if (!p->fname[0])
- fprintf (stderr, " .\n");
- else if (!strcmp (p->fname, "/") || !strcmp (p->fname, "//"))
- fprintf (stderr, " %s\n", p->fname);
- else
- /* Omit trailing '/'. */
- fprintf (stderr, " %.*s\n", (int) strlen (p->fname) - 1, p->fname);
- }
- notice ("End of search list.\n");
- {
- struct default_include * d;
- notice ("The following default directories have been omitted from the search path:\n");
- for (d = include_defaults; d->fname; d++)
- if (! d->included)
- fprintf (stderr, " %s\n", d->fname);
- notice ("End of omitted list.\n");
- }
- }
-
- /* -MG doesn't select the form of output and must be specified with one of
- -M or -MM. -MG doesn't make sense with -MD or -MMD since they don't
- inhibit compilation. */
- if (print_deps_missing_files && (print_deps == 0 || !inhibit_output))
- fatal ("-MG must be specified with one of -M or -MM");
-
- /* Either of two environment variables can specify output of deps.
- Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
- where OUTPUT_FILE is the file to write deps info to
- and DEPS_TARGET is the target to mention in the deps. */
-
- if (print_deps == 0
- && (getenv ("SUNPRO_DEPENDENCIES") != 0
- || getenv ("DEPENDENCIES_OUTPUT") != 0)) {
- char *spec = getenv ("DEPENDENCIES_OUTPUT");
- char *s;
- char *output_file;
-
- if (spec == 0) {
- spec = getenv ("SUNPRO_DEPENDENCIES");
- print_deps = 2;
- }
- else
- print_deps = 1;
-
- /* Find the space before the DEPS_TARGET, if there is one. */
- s = index (spec, ' ');
- if (s) {
- deps_target = s + 1;
- output_file = xmalloc (s - spec + 1);
- bcopy (spec, output_file, s - spec);
- output_file[s - spec] = 0;
- } else {
- deps_target = 0;
- output_file = spec;
- }
-
- deps_file = output_file;
- deps_mode = "a";
- }
-
- /* For -M, print the expected object file name
- as the target of this Make-rule. */
- if (print_deps) {
- deps_allocated_size = 200;
- deps_buffer = xmalloc (deps_allocated_size);
- deps_buffer[0] = 0;
- deps_size = 0;
- deps_column = 0;
-
- if (deps_target) {
- deps_output (deps_target, ':');
- } else if (*in_fname == 0) {
- deps_output ("-", ':');
- } else {
- char *p, *q;
- int len;
-
- q = base_name (in_fname);
-
- /* Copy remainder to mungable area. */
- p = (char *) alloca (strlen(q) + 8);
- strcpy (p, q);
-
- /* Output P, but remove known suffixes. */
- len = strlen (p);
- q = p + len;
- if (len >= 2
- && p[len - 2] == '.'
- && index("cCsSm", p[len - 1]))
- q = p + (len - 2);
- else if (len >= 3
- && p[len - 3] == '.'
- && p[len - 2] == 'c'
- && p[len - 1] == 'c')
- q = p + (len - 3);
- else if (len >= 4
- && p[len - 4] == '.'
- && p[len - 3] == 'c'
- && p[len - 2] == 'x'
- && p[len - 1] == 'x')
- q = p + (len - 4);
- else if (len >= 4
- && p[len - 4] == '.'
- && p[len - 3] == 'c'
- && p[len - 2] == 'p'
- && p[len - 1] == 'p')
- q = p + (len - 4);
-
- /* Supply our own suffix. */
- strcpy (q, OBJECT_SUFFIX);
-
- deps_output (p, ':');
- }
-
- deps_output (in_fname, ' ');
- }
-
- /* Scan the -imacros files before the main input.
- Much like #including them, but with no_output set
- so that only their macro definitions matter. */
-
- no_output++; no_record_file++;
- for (i = 1; i < argc; i++)
- if (pend_files[i]) {
- struct include_file *inc;
- int fd = open_include_file (pend_files[i], NULL_PTR, NULL_PTR, &inc);
- if (fd < 0) {
- perror_with_name (pend_files[i]);
- return FATAL_EXIT_CODE;
- }
- finclude (fd, inc, &outbuf, 0, NULL_PTR);
- }
- no_output--; no_record_file--;
-
- /* Copy the entire contents of the main input file into
- the stacked input buffer previously allocated for it. */
-
- /* JF check for stdin */
- if (in_fname == NULL || *in_fname == 0) {
- in_fname = "";
- f = 0;
- } else if ((f = open (in_fname, O_RDONLY, 0666)) < 0)
- goto perror;
-
- if (fstat (f, &st) != 0)
- pfatal_with_name (in_fname);
- fp->nominal_fname = fp->fname = in_fname;
- fp->nominal_fname_len = strlen (in_fname);
- fp->lineno = 1;
- fp->system_header_p = 0;
- /* JF all this is mine about reading pipes and ttys */
- if (! S_ISREG (st.st_mode)) {
- /* Read input from a file that is not a normal disk file.
- We cannot preallocate a buffer with the correct size,
- so we must read in the file a piece at the time and make it bigger. */
- int size;
- int bsize;
- int cnt;
-
- if (S_ISDIR (st.st_mode))
- fatal ("Input file `%s' is a directory", in_fname);
-
- bsize = 2000;
- size = 0;
- fp->buf = (U_CHAR *) xmalloc (bsize + 2);
- for (;;) {
- cnt = safe_read (f, (char *) fp->buf + size, bsize - size);
- if (cnt < 0) goto perror; /* error! */
- size += cnt;
- if (size != bsize) break; /* End of file */
- bsize *= 2;
- fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
- }
- fp->length = size;
- } else {
- /* Read a file whose size we can determine in advance.
- For the sake of VMS, st.st_size is just an upper bound. */
- size_t s = (size_t) st.st_size;
- if (s != st.st_size || s + 2 < s)
- memory_full ();
- fp->buf = (U_CHAR *) xmalloc (s + 2);
- fp->length = safe_read (f, (char *) fp->buf, s);
- if (fp->length < 0) goto perror;
- }
- fp->bufp = fp->buf;
- fp->if_stack = if_stack;
-
- /* Make sure data ends with a newline. And put a null after it. */
-
- if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
- /* Backslash-newline at end is not good enough. */
- || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
- fp->buf[fp->length++] = '\n';
- missing_newline = 1;
- }
- fp->buf[fp->length] = '\0';
-
- /* Unless inhibited, convert trigraphs in the input. */
-
- if (!no_trigraphs)
- trigraph_pcp (fp);
-
- if (warn_white_space)
- check_white_space (fp);
-
- /* Now that we know the input file is valid, open the output. */
-
- if (!out_fname || !strcmp (out_fname, ""))
- out_fname = "stdout";
- else if (! freopen (out_fname, "w", stdout))
- pfatal_with_name (out_fname);
-
- output_line_directive (fp, &outbuf, 0, same_file);
-
- /* Scan the -include files before the main input. */
-
- no_record_file++;
- for (i = 1; i < argc; i++)
- if (pend_includes[i]) {
- struct include_file *inc;
- int fd = open_include_file (pend_includes[i], NULL_PTR, NULL_PTR, &inc);
- if (fd < 0) {
- perror_with_name (pend_includes[i]);
- return FATAL_EXIT_CODE;
- }
- finclude (fd, inc, &outbuf, 0, NULL_PTR);
- }
- no_record_file--;
-
- /* Scan the input, processing macros and directives. */
-
- rescan (&outbuf, 0);
-
- if (missing_newline)
- fp->lineno--;
-
- if (pedantic && missing_newline)
- pedwarn ("file does not end in newline");
-
- /* Now we have processed the entire input
- Write whichever kind of output has been requested. */
-
- if (dump_macros == dump_only)
- dump_all_macros ();
- else if (! inhibit_output) {
- write_output ();
- }
-
- if (print_deps) {
- /* Don't actually write the deps file if compilation has failed. */
- if (errors == 0) {
- if (deps_file && ! (deps_stream = fopen (deps_file, deps_mode)))
- pfatal_with_name (deps_file);
- fputs (deps_buffer, deps_stream);
- putc ('\n', deps_stream);
- if (deps_file) {
- if (ferror (deps_stream) || fclose (deps_stream) != 0)
- fatal ("I/O error on output");
- }
- }
- }
-
- if (pcp_outfile && pcp_outfile != stdout
- && (ferror (pcp_outfile) || fclose (pcp_outfile) != 0))
- fatal ("I/O error on `-pcp' output");
-
- if (ferror (stdout) || fclose (stdout) != 0)
- fatal ("I/O error on output");
-
- if (errors)
- exit (FATAL_EXIT_CODE);
- exit (SUCCESS_EXIT_CODE);
-
- perror:
- pfatal_with_name (in_fname);
- return 0;
-}
-
-/* Given a colon-separated list of file names PATH,
- add all the names to the search path for include files. */
-
-static void
-path_include (path)
- char *path;
-{
- char *p;
-
- p = path;
-
- if (*p)
- while (1) {
- char *q = p;
- char c;
- struct file_name_list *dirtmp;
-
- /* Find the end of this name. */
- while ((c = *q++) != PATH_SEPARATOR && c)
- continue;
-
- q[-1] = 0;
- dirtmp = new_include_prefix (last_include, NULL_PTR,
- "", p == q ? "." : p);
- q[-1] = c;
- append_include_chain (dirtmp, dirtmp);
-
- /* Advance past this name. */
- p = q;
- if (! c)
- break;
- }
-}
-
-/* Return the address of the first character in S that equals C.
- S is an array of length N, possibly containing '\0's, and followed by '\0'.
- Return 0 if there is no such character. Assume that C itself is not '\0'.
- If we knew we could use memchr, we could just invoke memchr (S, C, N),
- but unfortunately memchr isn't autoconfigured yet. */
-
-static const U_CHAR *
-index0 (s, c, n)
- const U_CHAR *s;
- int c;
- size_t n;
-{
- const char *p = (const char *) s;
- for (;;) {
- const char *q = index (p, c);
- if (q)
- return (const U_CHAR *) q;
- else {
- size_t l = strlen (p);
- if (l == n)
- return 0;
- l++;
- p += l;
- n -= l;
- }
- }
-}
-
-/* Pre-C-Preprocessor to translate ANSI trigraph idiocy in BUF
- before main CCCP processing. Name `pcp' is also in honor of the
- drugs the trigraph designers must have been on.
-
- Using an extra pass through the buffer takes a little extra time,
- but is infinitely less hairy than trying to handle trigraphs inside
- strings, etc. everywhere, and also makes sure that trigraphs are
- only translated in the top level of processing. */
-
-static void
-trigraph_pcp (buf)
- FILE_BUF *buf;
-{
- register U_CHAR c, *bptr;
- register const U_CHAR *fptr, *sptr, *lptr;
- int len;
-
- fptr = sptr = bptr = buf->buf;
- lptr = fptr + buf->length;
- while ((sptr = index0 (sptr, '?', (size_t) (lptr - sptr))) != NULL) {
- if (*++sptr != '?')
- continue;
- switch (*++sptr) {
- case '=':
- c = '#';
- break;
- case '(':
- c = '[';
- break;
- case '/':
- c = '\\';
- break;
- case ')':
- c = ']';
- break;
- case '\'':
- c = '^';
- break;
- case '<':
- c = '{';
- break;
- case '!':
- c = '|';
- break;
- case '>':
- c = '}';
- break;
- case '-':
- c = '~';
- break;
- case '?':
- sptr--;
- continue;
- default:
- continue;
- }
- len = sptr - fptr - 2;
-
- /* BSD doc says bcopy () works right for overlapping strings. In ANSI
- C, this will be memmove (). */
- if (bptr != fptr && len > 0)
- bcopy ((const PTR) fptr, (PTR) bptr, len);
-
- bptr += len;
- *bptr++ = c;
- fptr = ++sptr;
- }
- len = buf->length - (fptr - buf->buf);
- if (bptr != fptr && len > 0)
- bcopy ((const PTR) fptr, (PTR) bptr, len);
- buf->length -= fptr - bptr;
- buf->buf[buf->length] = '\0';
- if (warn_trigraphs && fptr != bptr)
- warning_with_line (0, "%lu trigraph(s) encountered",
- (unsigned long) (fptr - bptr) / 2);
-}
-
-/* Warn about white space between backslash and end of line. */
-
-static void
-check_white_space (buf)
- FILE_BUF *buf;
-{
- register const U_CHAR *sptr = buf->buf;
- register const U_CHAR *lptr = sptr + buf->length;
- register const U_CHAR *nptr;
- int line = 0;
-
- nptr = sptr = buf->buf;
- lptr = sptr + buf->length;
- for (nptr = sptr;
- (nptr = index0 (nptr, '\n', (size_t) (lptr - nptr))) != NULL;
- nptr ++) {
- register const U_CHAR *p = nptr;
- line++;
- for (p = nptr; sptr < p; p--) {
- if (! is_hor_space[p[-1]]) {
- if (p[-1] == '\\' && p != nptr)
- warning_with_line (line,
- "`\\' followed by white space at end of line");
- break;
- }
- }
- }
-}
-
-/* Move all backslash-newline pairs out of embarrassing places.
- Exchange all such pairs following BP
- with any potentially-embarrassing characters that follow them.
- Potentially-embarrassing characters are / and *
- (because a backslash-newline inside a comment delimiter
- would cause it not to be recognized).
- We assume that *BP == '\\'. */
-
-static void
-newline_fix (bp)
- U_CHAR *bp;
-{
- register U_CHAR *p = bp;
-
- /* First count the backslash-newline pairs here. */
- do {
- if (p[1] != '\n')
- break;
- p += 2;
- } while (*p == '\\');
-
- /* What follows the backslash-newlines is not embarrassing. */
-
- if (*p != '/' && *p != '*')
- /* What follows the backslash-newlines is not embarrassing. */
- return;
-
- /* Copy all potentially embarrassing characters
- that follow the backslash-newline pairs
- down to where the pairs originally started. */
- do
- *bp++ = *p++;
- while (*p == '*' || *p == '/');
-
- /* Now write the same number of pairs after the embarrassing chars. */
- while (bp < p) {
- *bp++ = '\\';
- *bp++ = '\n';
- }
-}
-
-/* Like newline_fix but for use within a directive-name.
- Move any backslash-newlines up past any following symbol constituents. */
-
-static void
-name_newline_fix (bp)
- U_CHAR *bp;
-{
- register U_CHAR *p = bp;
-
- /* First count the backslash-newline pairs here. */
- do {
- if (p[1] != '\n')
- break;
- p += 2;
- } while (*p == '\\');
-
- /* What follows the backslash-newlines is not embarrassing. */
-
- if (!is_idchar[*p])
- /* What follows the backslash-newlines is not embarrassing. */
- return;
-
- /* Copy all potentially embarrassing characters
- that follow the backslash-newline pairs
- down to where the pairs originally started. */
- do
- *bp++ = *p++;
- while (is_idchar[*p]);
-
- /* Now write the same number of pairs after the embarrassing chars. */
- while (bp < p) {
- *bp++ = '\\';
- *bp++ = '\n';
- }
-}
-
-/* Look for lint commands in comments.
-
- When we come in here, ibp points into a comment. Limit is as one expects.
- scan within the comment -- it should start, after lwsp, with a lint command.
- If so that command is returned as a (constant) string.
-
- Upon return, any arg will be pointed to with argstart and will be
- arglen long. Note that we don't parse that arg since it will just
- be printed out again. */
-
-static const char *
-get_lintcmd (ibp, limit, argstart, arglen, cmdlen)
- register const U_CHAR *ibp;
- register const U_CHAR *limit;
- const U_CHAR **argstart; /* point to command arg */
- int *arglen, *cmdlen; /* how long they are */
-{
- HOST_WIDEST_INT linsize;
- register const U_CHAR *numptr; /* temp for arg parsing */
-
- *arglen = 0;
-
- SKIP_WHITE_SPACE (ibp);
-
- if (ibp >= limit) return NULL;
-
- linsize = limit - ibp;
-
- /* Oh, I wish C had lexical functions... hell, I'll just open-code the set */
- if ((linsize >= 10) && !bcmp (ibp, "NOTREACHED", 10)) {
- *cmdlen = 10;
- return "NOTREACHED";
- }
- if ((linsize >= 8) && !bcmp (ibp, "ARGSUSED", 8)) {
- *cmdlen = 8;
- return "ARGSUSED";
- }
- if ((linsize >= 11) && !bcmp (ibp, "LINTLIBRARY", 11)) {
- *cmdlen = 11;
- return "LINTLIBRARY";
- }
- if ((linsize >= 7) && !bcmp (ibp, "VARARGS", 7)) {
- *cmdlen = 7;
- ibp += 7; linsize -= 7;
- if ((linsize == 0) || ! ISDIGIT (*ibp)) return "VARARGS";
-
- /* OK, read a number */
- for (numptr = *argstart = ibp; (numptr < limit) && ISDIGIT (*numptr);
- numptr++);
- *arglen = numptr - *argstart;
- return "VARARGS";
- }
- return NULL;
-}
-
-/*
- * The main loop of the program.
- *
- * Read characters from the input stack, transferring them to the
- * output buffer OP.
- *
- * Macros are expanded and push levels on the input stack.
- * At the end of such a level it is popped off and we keep reading.
- * At the end of any other kind of level, we return.
- * #-directives are handled, except within macros.
- *
- * If OUTPUT_MARKS is nonzero, keep Newline markers found in the input
- * and insert them when appropriate. This is set while scanning macro
- * arguments before substitution. It is zero when scanning for final output.
- * There are two types of Newline markers:
- * * Newline - follows a macro name that was not expanded
- * because it appeared inside an expansion of the same macro.
- * This marker prevents future expansion of that identifier.
- * When the input is rescanned into the final output, these are deleted.
- * These are also deleted by ## concatenation.
- * * Newline Space (or Newline and any other whitespace character)
- * stands for a place that tokens must be separated or whitespace
- * is otherwise desirable, but where the ANSI standard specifies there
- * is no whitespace. This marker turns into a Space (or whichever other
- * whitespace char appears in the marker) in the final output,
- * but it turns into nothing in an argument that is stringified with #.
- * Such stringified arguments are the only place where the ANSI standard
- * specifies with precision that whitespace may not appear.
- *
- * During this function, IP->bufp is kept cached in IBP for speed of access.
- * Likewise, OP->bufp is kept in OBP. Before calling a subroutine
- * IBP, IP and OBP must be copied back to memory. IP and IBP are
- * copied back with the RECACHE macro. OBP must be copied back from OP->bufp
- * explicitly, and before RECACHE, since RECACHE uses OBP.
- */
-
-static void
-rescan (op, output_marks)
- FILE_BUF *op;
- int output_marks;
-{
- /* Character being scanned in main loop. */
- register U_CHAR c;
-
- /* Length of pending accumulated identifier. */
- register int ident_length = 0;
-
- /* Hash code of pending accumulated identifier. */
- register int hash = 0;
-
- /* Current input level (&instack[indepth]). */
- FILE_BUF *ip;
-
- /* Pointer for scanning input. */
- register U_CHAR *ibp;
-
- /* Pointer to end of input. End of scan is controlled by LIMIT. */
- register U_CHAR *limit;
-
- /* Pointer for storing output. */
- register U_CHAR *obp;
-
- /* REDO_CHAR is nonzero if we are processing an identifier
- after backing up over the terminating character.
- Sometimes we process an identifier without backing up over
- the terminating character, if the terminating character
- is not special. Backing up is done so that the terminating character
- will be dispatched on again once the identifier is dealt with. */
- int redo_char = 0;
-
- /* 1 if within an identifier inside of which a concatenation
- marker (Newline -) has been seen. */
- int concatenated = 0;
-
- /* While scanning a comment or a string constant,
- this records the line it started on, for error messages. */
- int start_line;
-
- /* Record position of last `real' newline. */
- U_CHAR *beg_of_line;
-
-/* Pop the innermost input stack level, assuming it is a macro expansion. */
-
-#define POPMACRO \
-do { ip->macro->type = T_MACRO; \
- if (ip->free_ptr) free (ip->free_ptr); \
- --indepth; } while (0)
-
-/* Reload `rescan's local variables that describe the current
- level of the input stack. */
-
-#define RECACHE \
-do { ip = &instack[indepth]; \
- ibp = ip->bufp; \
- limit = ip->buf + ip->length; \
- op->bufp = obp; \
- check_expand (op, limit - ibp); \
- beg_of_line = 0; \
- obp = op->bufp; } while (0)
-
- if (no_output && instack[indepth].fname != 0)
- skip_if_group (&instack[indepth], 1, NULL);
-
- obp = op->bufp;
- RECACHE;
-
- beg_of_line = ibp;
-
- /* Our caller must always put a null after the end of
- the input at each input stack level. */
- if (*limit != 0)
- abort ();
-
- while (1) {
- c = *ibp++;
- *obp++ = c;
-
- switch (c) {
- case '\\':
- if (*ibp == '\n' && !ip->macro) {
- /* At the top level, always merge lines ending with backslash-newline,
- even in middle of identifier. But do not merge lines in a macro,
- since backslash might be followed by a newline-space marker. */
- ++ibp;
- ++ip->lineno;
- --obp; /* remove backslash from obuf */
- break;
- }
- /* If ANSI, backslash is just another character outside a string. */
- if (!traditional)
- goto randomchar;
- /* Otherwise, backslash suppresses specialness of following char,
- so copy it here to prevent the switch from seeing it.
- But first get any pending identifier processed. */
- if (ident_length > 0)
- goto specialchar;
- if (ibp < limit)
- *obp++ = *ibp++;
- break;
-
- case '%':
- if (ident_length || ip->macro || traditional)
- goto randomchar;
- while (*ibp == '\\' && ibp[1] == '\n') {
- ibp += 2;
- ++ip->lineno;
- }
- if (*ibp != ':')
- break;
- /* Treat this %: digraph as if it were #. */
- /* Fall through. */
-
- case '#':
- if (assertions_flag) {
- if (ident_length)
- goto specialchar;
- /* Copy #foo (bar lose) without macro expansion. */
- obp[-1] = '#'; /* In case it was '%'. */
- SKIP_WHITE_SPACE (ibp);
- while (is_idchar[*ibp])
- *obp++ = *ibp++;
- SKIP_WHITE_SPACE (ibp);
- if (*ibp == '(') {
- ip->bufp = ibp;
- skip_paren_group (ip);
- bcopy ((const PTR) ibp, (PTR) obp, ip->bufp - ibp);
- obp += ip->bufp - ibp;
- ibp = ip->bufp;
- }
- break;
- }
-
- /* If this is expanding a macro definition, don't recognize
- preprocessing directives. */
- if (ip->macro != 0)
- goto randomchar;
- /* If this is expand_into_temp_buffer,
- don't recognize them either. Warn about them
- only after an actual newline at this level,
- not at the beginning of the input level. */
- if (! ip->fname) {
- if (ip->buf != beg_of_line)
- warning ("preprocessing directive not recognized within macro arg");
- goto randomchar;
- }
- if (ident_length)
- goto specialchar;
-
-
- /* # keyword: a # must be first nonblank char on the line */
- if (beg_of_line == 0)
- goto randomchar;
- {
- U_CHAR *bp;
-
- /* Scan from start of line, skipping whitespace, comments
- and backslash-newlines, and see if we reach this #.
- If not, this # is not special. */
- bp = beg_of_line;
- /* If -traditional, require # to be at beginning of line. */
- if (!traditional) {
- while (1) {
- if (is_hor_space[*bp])
- bp++;
- else if (*bp == '\\' && bp[1] == '\n')
- bp += 2;
- else if (*bp == '/' && bp[1] == '*') {
- bp += 2;
- while (1)
- {
- if (*bp == '*')
- {
- if (bp[1] == '/')
- {
- bp += 2;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- bp++;
- }
- }
- /* There is no point in trying to deal with C++ // comments here,
- because if there is one, then this # must be part of the
- comment and we would never reach here. */
- else break;
- }
- if (c == '%') {
- if (bp[0] != '%')
- break;
- while (bp[1] == '\\' && bp[2] == '\n')
- bp += 2;
- if (bp + 1 != ibp)
- break;
- /* %: appears at start of line; skip past the ':' too. */
- bp++;
- ibp++;
- }
- }
- if (bp + 1 != ibp)
- goto randomchar;
- }
-
- /* This # can start a directive. */
-
- --obp; /* Don't copy the '#' */
-
- ip->bufp = ibp;
- op->bufp = obp;
- if (! handle_directive (ip, op)) {
-#ifdef USE_C_ALLOCA
- alloca (0);
-#endif
- /* Not a known directive: treat it as ordinary text.
- IP, OP, IBP, etc. have not been changed. */
- if (no_output && instack[indepth].fname) {
- /* If not generating expanded output,
- what we do with ordinary text is skip it.
- Discard everything until next # directive. */
- skip_if_group (&instack[indepth], 1, 0);
- RECACHE;
- beg_of_line = ibp;
- break;
- }
- *obp++ = '#'; /* Copy # (even if it was originally %:). */
- /* Don't expand an identifier that could be a macro directive.
- (Section 3.8.3 of the ANSI C standard) */
- SKIP_WHITE_SPACE (ibp);
- if (is_idstart[*ibp])
- {
- *obp++ = *ibp++;
- while (is_idchar[*ibp])
- *obp++ = *ibp++;
- }
- goto randomchar;
- }
-#ifdef USE_C_ALLOCA
- alloca (0);
-#endif
- /* A # directive has been successfully processed. */
- /* If not generating expanded output, ignore everything until
- next # directive. */
- if (no_output && instack[indepth].fname)
- skip_if_group (&instack[indepth], 1, 0);
- obp = op->bufp;
- RECACHE;
- beg_of_line = ibp;
- break;
-
- case '\"': /* skip quoted string */
- case '\'':
- /* A single quoted string is treated like a double -- some
- programs (e.g., troff) are perverse this way */
-
- /* Handle any pending identifier;
- but the L in L'...' or L"..." is not an identifier. */
- if (ident_length) {
- if (! (ident_length == 1 && hash == HASHSTEP (0, 'L')))
- goto specialchar;
- ident_length = hash = 0;
- }
-
- start_line = ip->lineno;
-
- /* Skip ahead to a matching quote. */
-
- while (1) {
- if (ibp >= limit) {
- if (ip->macro != 0) {
- /* try harder: this string crosses a macro expansion boundary.
- This can happen naturally if -traditional.
- Otherwise, only -D can make a macro with an unmatched quote. */
- POPMACRO;
- RECACHE;
- continue;
- }
- if (!traditional) {
- error_with_line (line_for_error (start_line),
- "unterminated string or character constant");
- if (multiline_string_line) {
- error_with_line (multiline_string_line,
- "possible real start of unterminated constant");
- multiline_string_line = 0;
- }
- }
- break;
- }
- *obp++ = *ibp;
- switch (*ibp++) {
- case '\n':
- if (warn_white_space && ip->fname && is_hor_space[ibp[-2]])
- warning ("white space at end of line in string");
- ++ip->lineno;
- ++op->lineno;
- /* Traditionally, end of line ends a string constant with no error.
- So exit the loop and record the new line. */
- if (traditional) {
- beg_of_line = ibp;
- goto while2end;
- }
- if (c == '\'') {
- error_with_line (line_for_error (start_line),
- "unterminated character constant");
- goto while2end;
- }
- if (multiline_string_line == 0) {
- if (pedantic)
- pedwarn_with_line (line_for_error (start_line),
- "string constant runs past end of line");
- multiline_string_line = ip->lineno - 1;
- }
- break;
-
- case '\\':
- if (*ibp == '\n') {
- /* Backslash newline is replaced by nothing at all, but
- keep the line counts correct. But if we are reading
- from a macro, keep the backslash newline, since backslash
- newlines have already been processed. */
- if (ip->macro) {
- *obp++ = '\n';
- ++op->lineno;
- } else
- --obp;
- ++ibp;
- ++ip->lineno;
- } else {
- /* ANSI stupidly requires that in \\ the second \
- is *not* prevented from combining with a newline. */
- if (!ip->macro) {
- while (*ibp == '\\' && ibp[1] == '\n') {
- *obp++ = *ibp++;
- *obp++ = *ibp++;
- ++ip->lineno;
- ++op->lineno;
- }
- }
- *obp++ = *ibp++;
- }
- break;
-
- case '\"':
- case '\'':
- if (ibp[-1] == c)
- goto while2end;
- break;
-#ifdef MULTIBYTE_CHARS
- default:
- {
- int length;
- --ibp;
- length = local_mblen (ibp, limit - ibp);
- if (length > 0)
- {
- --obp;
- bcopy (ibp, obp, length);
- obp += length;
- ibp += length;
- }
- else
- ++ibp;
- }
- break;
-#endif
- }
- }
- while2end:
- break;
-
- case '/':
- if (ip->macro != 0)
- goto randomchar;
- if (*ibp == '\\')
- newline_fix (ibp);
- if (*ibp != '*'
- && !(cplusplus_comments && *ibp == '/'))
- goto randomchar;
- if (ident_length)
- goto specialchar;
-
- if (*ibp == '/') {
- /* C++ style comment... */
- start_line = ip->lineno;
-
- /* Comments are equivalent to spaces. */
- if (! put_out_comments)
- obp[-1] = ' ';
-
- {
- U_CHAR *before_bp = ibp;
-
- while (++ibp < limit) {
- if (*ibp == '\n')
- {
- if (put_out_comments) {
- bcopy ((const PTR) before_bp, (PTR) obp, ibp - before_bp);
- obp += ibp - before_bp;
- }
- break;
- }
- if (*ibp == '\\')
- {
- if (ibp + 1 < limit && ibp[1] == '\n')
- {
- if (warn_comments)
- warning ("multiline `//' comment");
- ++ip->lineno;
- /* Copy the newline into the output buffer, in order to
- avoid the pain of a #line every time a multiline comment
- is seen. */
- if (!put_out_comments)
- *obp++ = '\n';
- ++op->lineno;
- ++ibp;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- ibp += (length - 1);
-#endif
- }
- }
- break;
- }
- }
-
- /* Ordinary C comment. Skip it, optionally copying it to output. */
-
- start_line = ip->lineno;
-
- ++ibp; /* Skip the star. */
-
- /* If this cpp is for lint, we peek inside the comments: */
- if (for_lint) {
- const U_CHAR *argbp;
- int cmdlen, arglen;
- const char *lintcmd =
- get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen);
-
- if (lintcmd != NULL) {
- op->bufp = obp;
- check_expand (op, cmdlen + arglen + 14);
- obp = op->bufp;
- /* I believe it is always safe to emit this newline: */
- obp[-1] = '\n';
- bcopy ("#pragma lint ", (char *) obp, 13);
- obp += 13;
- bcopy (lintcmd, (char *) obp, cmdlen);
- obp += cmdlen;
-
- if (arglen != 0) {
- *(obp++) = ' ';
- bcopy (argbp, (char *) obp, arglen);
- obp += arglen;
- }
-
- /* OK, now bring us back to the state we were in before we entered
- this branch. We need #line because the #pragma's newline always
- messes up the line count. */
- op->bufp = obp;
- output_line_directive (ip, op, 0, same_file);
- check_expand (op, limit - ibp + 2);
- obp = op->bufp;
- *(obp++) = '/';
- }
- }
-
- /* Comments are equivalent to spaces.
- Note that we already output the slash; we might not want it.
- For -traditional, a comment is equivalent to nothing. */
- if (! put_out_comments) {
- if (traditional)
- obp--;
- else
- obp[-1] = ' ';
- }
- else
- *obp++ = '*';
-
- {
- U_CHAR *before_bp = ibp;
-
- for (;;) {
- switch (*ibp++) {
- case '*':
- if (ibp[-2] == '/' && warn_comments)
- warning ("`/*' within comment");
- if (*ibp == '\\')
- newline_fix (ibp);
- if (*ibp == '/')
- goto comment_end;
- break;
-
- case '\n':
- ++ip->lineno;
- /* Copy the newline into the output buffer, in order to
- avoid the pain of a #line every time a multiline comment
- is seen. */
- if (!put_out_comments)
- *obp++ = '\n';
- ++op->lineno;
- break;
-
- case 0:
- if (limit < ibp) {
- error_with_line (line_for_error (start_line),
- "unterminated comment");
- goto limit_reached;
- }
- break;
-#ifdef MULTIBYTE_CHARS
- default:
- {
- int length;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- ibp += (length - 1);
- }
- break;
-#endif
- }
- }
- comment_end:
-
- ibp++;
- if (put_out_comments) {
- bcopy ((const PTR) before_bp, (PTR) obp, ibp - before_bp);
- obp += ibp - before_bp;
- }
- }
- break;
-
- case '$':
- if (! is_idchar['$'])
- goto randomchar;
- if (pedantic)
- pedwarn ("`$' in identifier");
- goto letter;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- /* If digit is not part of identifier, it starts a number,
- which means that following letters are not an identifier.
- "0x5" does not refer to an identifier "x5".
- So copy all alphanumerics that follow without accumulating
- as an identifier. Periods also, for sake of "3.e7". */
-
- if (ident_length == 0) {
- for (;;) {
- if (!ip->macro) {
- while (ibp[0] == '\\' && ibp[1] == '\n') {
- ++ip->lineno;
- ibp += 2;
- }
- }
- c = *ibp++;
- if (!is_idchar[c] && c != '.') {
- --ibp;
- break;
- }
- *obp++ = c;
- /* A sign can be part of a preprocessing number
- if it follows an `e' or `p'. */
- if (c == 'e' || c == 'E' || c == 'p' || c == 'P') {
- if (!ip->macro) {
- while (ibp[0] == '\\' && ibp[1] == '\n') {
- ++ip->lineno;
- ibp += 2;
- }
- }
- if (*ibp == '+' || *ibp == '-') {
- *obp++ = *ibp++;
- /* But traditional C does not let the token go past the sign,
- and C89 does not allow `p'. */
- if (traditional || (c89 && (c == 'p' || c == 'P')))
- break;
- }
- }
- }
- break;
- }
- /* fall through */
-
- case '_':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- letter:
- ident_length++;
- /* Compute step of hash function, to avoid a proc call on every token */
- hash = HASHSTEP (hash, c);
- break;
-
- case '\n':
- if (ip->fname == 0 && *ibp == '-') {
- /* Newline - inhibits expansion of preceding token.
- If expanding a macro arg, we keep the newline -.
- In final output, it is deleted.
- We recognize Newline - in macro bodies and macro args. */
- if (! concatenated) {
- ident_length = 0;
- hash = 0;
- }
- ibp++;
- if (!output_marks) {
- obp--;
- } else {
- /* If expanding a macro arg, keep the newline -. */
- *obp++ = '-';
- }
- break;
- }
-
- /* If reprocessing a macro expansion, newline is a special marker. */
- else if (ip->macro != 0) {
- /* Newline White is a "funny space" to separate tokens that are
- supposed to be separate but without space between.
- Here White means any whitespace character.
- Newline - marks a recursive macro use that is not
- supposed to be expandable. */
-
- if (is_space[*ibp]) {
- /* Newline Space does not prevent expansion of preceding token
- so expand the preceding token and then come back. */
- if (ident_length > 0)
- goto specialchar;
-
- /* If generating final output, newline space makes a space. */
- if (!output_marks) {
- obp[-1] = *ibp++;
- /* And Newline Newline makes a newline, so count it. */
- if (obp[-1] == '\n')
- op->lineno++;
- } else {
- /* If expanding a macro arg, keep the newline space.
- If the arg gets stringified, newline space makes nothing. */
- *obp++ = *ibp++;
- }
- } else abort (); /* Newline followed by something random? */
- break;
- }
-
- /* If there is a pending identifier, handle it and come back here. */
- if (ident_length > 0)
- goto specialchar;
-
- beg_of_line = ibp;
-
- /* Update the line counts and output a #line if necessary. */
- ++ip->lineno;
- ++op->lineno;
- if (ip->lineno != op->lineno) {
- op->bufp = obp;
- output_line_directive (ip, op, 1, same_file);
- check_expand (op, limit - ibp);
- obp = op->bufp;
- }
- break;
-
- /* Come here either after (1) a null character that is part of the input
- or (2) at the end of the input, because there is a null there. */
- case 0:
- if (ibp <= limit)
- /* Our input really contains a null character. */
- goto randomchar;
-
- limit_reached:
- /* At end of a macro-expansion level, pop it and read next level. */
- if (ip->macro != 0) {
- obp--;
- ibp--;
- /* If traditional, and we have an identifier that ends here,
- process it now, so we get the right error for recursion. */
- if (traditional && ident_length
- && ! is_idchar[*instack[indepth - 1].bufp]) {
- redo_char = 1;
- goto randomchar;
- }
- POPMACRO;
- RECACHE;
- break;
- }
-
- /* If we don't have a pending identifier,
- return at end of input. */
- if (ident_length == 0) {
- obp--;
- ibp--;
- op->bufp = obp;
- ip->bufp = ibp;
- goto ending;
- }
-
- /* If we do have a pending identifier, just consider this null
- a special character and arrange to dispatch on it again.
- The second time, IDENT_LENGTH will be zero so we will return. */
-
- /* Fall through */
-
-specialchar:
-
- /* Handle the case of a character such as /, ', " or null
- seen following an identifier. Back over it so that
- after the identifier is processed the special char
- will be dispatched on again. */
-
- ibp--;
- obp--;
- redo_char = 1;
-
- default:
-
-randomchar:
-
- if (ident_length > 0) {
- register HASHNODE *hp;
-
- /* We have just seen an identifier end. If it's a macro, expand it.
-
- IDENT_LENGTH is the length of the identifier
- and HASH is its hash code.
-
- The identifier has already been copied to the output,
- so if it is a macro we must remove it.
-
- If REDO_CHAR is 0, the char that terminated the identifier
- has been skipped in the output and the input.
- OBP-IDENT_LENGTH-1 points to the identifier.
- If the identifier is a macro, we must back over the terminator.
-
- If REDO_CHAR is 1, the terminating char has already been
- backed over. OBP-IDENT_LENGTH points to the identifier. */
-
- if (!pcp_outfile || pcp_inside_if) {
- for (hp = hashtab[MAKE_POS (hash) % HASHSIZE]; hp != NULL;
- hp = hp->next) {
-
- if (hp->length == ident_length) {
- int obufp_before_macroname;
- int op_lineno_before_macroname;
- register int i = ident_length;
- register U_CHAR *p = hp->name;
- register U_CHAR *q = obp - i;
- int disabled;
-
- if (! redo_char)
- q--;
-
- do { /* All this to avoid a strncmp () */
- if (*p++ != *q++)
- goto hashcollision;
- } while (--i);
-
- /* We found a use of a macro name.
- see if the context shows it is a macro call. */
-
- /* Back up over terminating character if not already done. */
- if (! redo_char) {
- ibp--;
- obp--;
- }
-
- /* Save this as a displacement from the beginning of the output
- buffer. We can not save this as a position in the output
- buffer, because it may get realloc'ed by RECACHE. */
- obufp_before_macroname = (obp - op->buf) - ident_length;
- op_lineno_before_macroname = op->lineno;
-
- if (hp->type == T_PCSTRING) {
- pcstring_used (hp); /* Mark the definition of this key
- as needed, ensuring that it
- will be output. */
- break; /* Exit loop, since the key cannot have a
- definition any longer. */
- }
-
- /* Record whether the macro is disabled. */
- disabled = hp->type == T_DISABLED;
-
- /* This looks like a macro ref, but if the macro was disabled,
- just copy its name and put in a marker if requested. */
-
- if (disabled) {
-#if 0
- /* This error check caught useful cases such as
- #define foo(x,y) bar (x (y,0), y)
- foo (foo, baz) */
- if (traditional)
- error ("recursive use of macro `%s'", hp->name);
-#endif
-
- if (output_marks) {
- op->bufp = obp;
- check_expand (op, limit - ibp + 2);
- obp = op->bufp;
- *obp++ = '\n';
- *obp++ = '-';
- }
- break;
- }
-
- /* If macro wants an arglist, verify that a '(' follows.
- first skip all whitespace, copying it to the output
- after the macro name. Then, if there is no '(',
- decide this is not a macro call and leave things that way. */
- if ((hp->type == T_MACRO || hp->type == T_DISABLED)
- && hp->value.defn->nargs >= 0)
- {
- U_CHAR *old_ibp = ibp;
- U_CHAR *old_obp = obp;
- int old_iln = ip->lineno;
- int old_oln = op->lineno;
-
- while (1) {
- /* Scan forward over whitespace, copying it to the output. */
- if (ibp == limit && ip->macro != 0) {
- POPMACRO;
- RECACHE;
- old_ibp = ibp;
- old_obp = obp;
- old_iln = ip->lineno;
- old_oln = op->lineno;
- }
- else if (is_space[*ibp]) {
- *obp++ = *ibp++;
- if (ibp[-1] == '\n') {
- if (ip->macro == 0) {
- /* Newline in a file. Count it. */
- ++ip->lineno;
- ++op->lineno;
- } else if (!output_marks) {
- /* A newline mark, and we don't want marks
- in the output. If it is newline-hyphen,
- discard it entirely. Otherwise, it is
- newline-whitechar, so keep the whitechar. */
- obp--;
- if (*ibp == '-')
- ibp++;
- else {
- if (*ibp == '\n')
- ++op->lineno;
- *obp++ = *ibp++;
- }
- } else {
- /* A newline mark; copy both chars to the output. */
- *obp++ = *ibp++;
- }
- }
- }
- else if (ip->macro)
- break;
- else if (*ibp == '/') {
- /* If a comment, copy it unchanged or discard it. */
- if (ibp[1] == '\\')
- newline_fix (ibp + 1);
- if (ibp[1] == '*') {
- if (put_out_comments) {
- *obp++ = '/';
- *obp++ = '*';
- } else if (! traditional) {
- *obp++ = ' ';
- }
- for (ibp += 2; ibp < limit; ibp++) {
- /* We need not worry about newline-marks,
- since they are never found in comments. */
- if (ibp[0] == '*') {
- if (ibp[1] == '\\')
- newline_fix (ibp + 1);
- if (ibp[1] == '/') {
- ibp += 2;
- if (put_out_comments) {
- *obp++ = '*';
- *obp++ = '/';
- }
- break;
- }
- }
- else if (*ibp == '\n') {
- /* Newline in a file. Count it. */
- ++ip->lineno;
- ++op->lineno;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- {
- if (put_out_comments)
- {
- bcopy (ibp, obp, length - 1);
- obp += length - 1;
- }
- ibp += (length - 1);
- }
-#endif
- }
- if (put_out_comments)
- *obp++ = *ibp;
- }
- } else if (ibp[1] == '/' && cplusplus_comments) {
- if (put_out_comments) {
- *obp++ = '/';
- *obp++ = '/';
- } else if (! traditional) {
- *obp++ = ' ';
- }
- for (ibp += 2; ; ibp++)
- {
- if (*ibp == '\n')
- break;
- if (*ibp == '\\' && ibp[1] == '\n')
- {
- if (put_out_comments)
- *obp++ = *ibp++;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- {
- if (put_out_comments)
- {
- bcopy (ibp, obp, length - 1);
- obp += length - 1;
- }
- ibp += (length - 1);
- }
-#endif
- }
- if (put_out_comments)
- *obp++ = *ibp;
- }
- } else
- break;
- }
- else if (ibp[0] == '\\' && ibp[1] == '\n') {
- ibp += 2;
- ++ip->lineno;
- }
- else break;
- }
- if (*ibp != '(') {
- /* It isn't a macro call.
- Put back the space that we just skipped. */
- ibp = old_ibp;
- obp = old_obp;
- ip->lineno = old_iln;
- op->lineno = old_oln;
- /* Exit the for loop. */
- break;
- }
- }
-
- /* This is now known to be a macro call.
- Discard the macro name from the output,
- along with any following whitespace just copied,
- but preserve newlines if not outputting marks since this
- is more likely to do the right thing with line numbers. */
- obp = op->buf + obufp_before_macroname;
- if (output_marks)
- op->lineno = op_lineno_before_macroname;
- else {
- int newlines = op->lineno - op_lineno_before_macroname;
- while (0 < newlines--)
- *obp++ = '\n';
- }
-
- /* Prevent accidental token-pasting with a character
- before the macro call. */
- if (!traditional && obp != op->buf) {
- switch (obp[-1]) {
- case '!': case '%': case '&': case '*':
- case '+': case '-': case '.': case '/':
- case ':': case '<': case '=': case '>':
- case '^': case '|':
- /* If we are expanding a macro arg, make a newline marker
- to separate the tokens. If we are making real output,
- a plain space will do. */
- if (output_marks)
- *obp++ = '\n';
- *obp++ = ' ';
- }
- }
-
- /* Expand the macro, reading arguments as needed,
- and push the expansion on the input stack. */
- ip->bufp = ibp;
- op->bufp = obp;
- macroexpand (hp, op);
-
- /* Reexamine input stack, since macroexpand has pushed
- a new level on it. */
- obp = op->bufp;
- RECACHE;
- break;
- }
-hashcollision:
- ;
- } /* End hash-table-search loop */
- }
- ident_length = hash = 0; /* Stop collecting identifier */
- redo_char = 0;
- concatenated = 0;
- } /* End if (ident_length > 0) */
- } /* End switch */
- } /* End per-char loop */
-
- /* Come here to return -- but first give an error message
- if there was an unterminated successful conditional. */
- ending:
- if (if_stack != ip->if_stack)
- {
- const char *str;
-
- switch (if_stack->type)
- {
- case T_IF:
- str = "if";
- break;
- case T_IFDEF:
- str = "ifdef";
- break;
- case T_IFNDEF:
- str = "ifndef";
- break;
- case T_ELSE:
- str = "else";
- break;
- case T_ELIF:
- str = "elif";
- break;
- default:
- abort ();
- }
-
- error_with_line (line_for_error (if_stack->lineno),
- "unterminated `#%s' conditional", str);
- }
- if_stack = ip->if_stack;
-}
-
-/*
- * Rescan a string into a temporary buffer and return the result
- * as a FILE_BUF. Note this function returns a struct, not a pointer.
- *
- * OUTPUT_MARKS nonzero means keep Newline markers found in the input
- * and insert such markers when appropriate. See `rescan' for details.
- * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately
- * before substitution; it is 0 for other uses.
- */
-static FILE_BUF
-expand_to_temp_buffer (buf, limit, output_marks, assertions)
- const U_CHAR *buf;
- const U_CHAR *limit;
- int output_marks, assertions;
-{
- register FILE_BUF *ip;
- FILE_BUF obuf;
- int length = limit - buf;
- U_CHAR *buf1;
- int odepth = indepth;
- int save_assertions_flag = assertions_flag;
-
- assertions_flag = assertions;
-
- if (length < 0)
- abort ();
-
- /* Set up the input on the input stack. */
-
- buf1 = (U_CHAR *) alloca (length + 1);
- {
- register const U_CHAR *p1 = buf;
- register U_CHAR *p2 = buf1;
-
- while (p1 != limit)
- *p2++ = *p1++;
- }
- buf1[length] = 0;
-
- /* Set up to receive the output. */
-
- obuf.length = length * 2 + 100; /* Usually enough. Why be stingy? */
- obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);
- obuf.nominal_fname = 0;
- obuf.inc = 0;
- obuf.dir = 0;
- obuf.fname = 0;
- obuf.macro = 0;
- obuf.if_stack = 0;
- obuf.free_ptr = 0;
- obuf.system_header_p = 0;
-
- CHECK_DEPTH ({return obuf;});
-
- ++indepth;
-
- ip = &instack[indepth];
- ip->fname = 0;
- ip->nominal_fname = 0;
- ip->nominal_fname_len = 0;
- ip->inc = 0;
- ip->system_header_p = 0;
- ip->macro = 0;
- ip->free_ptr = 0;
- ip->length = length;
- ip->buf = ip->bufp = buf1;
- ip->if_stack = if_stack;
-
- ip->lineno = obuf.lineno = 1;
-
- /* Scan the input, create the output. */
- rescan (&obuf, output_marks);
-
- /* Pop input stack to original state. */
- --indepth;
-
- if (indepth != odepth)
- abort ();
-
- assertions_flag = save_assertions_flag;
- return obuf;
-}
-
-/*
- * Process a # directive. Expects IP->bufp to point after the '#', as in
- * `#define foo bar'. Passes to the directive handler
- * (do_define, do_include, etc.): the addresses of the 1st and
- * last chars of the directive (starting immediately after the #
- * keyword), plus op and the keyword table pointer. If the directive
- * contains comments it is copied into a temporary buffer sans comments
- * and the temporary buffer is passed to the directive handler instead.
- * Likewise for backslash-newlines.
- *
- * Returns nonzero if this was a known # directive.
- * Otherwise, returns zero, without advancing the input pointer.
- */
-
-static int
-handle_directive (ip, op)
- FILE_BUF *ip, *op;
-{
- register U_CHAR *bp, *cp;
- register struct directive *kt;
- register int ident_length;
- U_CHAR *resume_p;
-
- /* Nonzero means we must copy the entire directive
- to get rid of comments or backslash-newlines. */
- int copy_directive = 0;
-
- U_CHAR *ident, *after_ident;
-
- bp = ip->bufp;
-
- /* Record where the directive started. do_xifdef needs this. */
- directive_start = bp - 1;
-
- ignore_escape_flag = 1;
-
- /* Skip whitespace and \-newline. */
- while (1) {
- if (is_hor_space[*bp]) {
- if (*bp != ' ' && *bp != '\t' && pedantic)
- pedwarn_strange_white_space (*bp);
- bp++;
- } else if (*bp == '/') {
- if (bp[1] == '\\')
- newline_fix (bp + 1);
- if (! (bp[1] == '*' || (cplusplus_comments && bp[1] == '/')))
- break;
- ip->bufp = bp + 2;
- skip_to_end_of_comment (ip, &ip->lineno, 0);
- bp = ip->bufp;
- } else if (*bp == '\\' && bp[1] == '\n') {
- bp += 2; ip->lineno++;
- } else break;
- }
-
- /* Now find end of directive name.
- If we encounter a backslash-newline, exchange it with any following
- symbol-constituents so that we end up with a contiguous name. */
-
- cp = bp;
- while (1) {
- if (is_idchar[*cp])
- cp++;
- else {
- if (*cp == '\\')
- name_newline_fix (cp);
- if (is_idchar[*cp])
- cp++;
- else break;
- }
- }
- ident_length = cp - bp;
- ident = bp;
- after_ident = cp;
-
- /* A line of just `#' becomes blank. */
-
- if (ident_length == 0 && *after_ident == '\n') {
- ip->bufp = after_ident;
- return 1;
- }
-
- if (ident_length == 0 || !is_idstart[*ident]) {
- U_CHAR *p = ident;
- while (is_idchar[*p]) {
- if (*p < '0' || *p > '9')
- break;
- p++;
- }
- /* Handle # followed by a line number. */
- if (p != ident && !is_idchar[*p]) {
- static struct directive line_directive_table[] = {
- { 4, do_line, "line", T_LINE},
- };
- if (pedantic)
- pedwarn ("`#' followed by integer");
- after_ident = ident;
- kt = line_directive_table;
- ignore_escape_flag = 0;
- goto old_linenum;
- }
-
- /* Avoid error for `###' and similar cases unless -pedantic. */
- if (p == ident) {
- while (*p == '#' || is_hor_space[*p]) p++;
- if (*p == '\n') {
- if (pedantic && !lang_asm)
- warning ("invalid preprocessing directive");
- return 0;
- }
- }
-
- if (!lang_asm)
- error ("invalid preprocessing directive name");
-
- return 0;
- }
-
- /*
- * Decode the keyword and call the appropriate expansion
- * routine, after moving the input pointer up to the next line.
- */
- for (kt = directive_table; kt->length > 0; kt++) {
- if (kt->length == ident_length && !bcmp (kt->name, ident, ident_length)) {
- register U_CHAR *buf;
- register U_CHAR *limit;
- int unterminated;
- int junk;
- int *already_output;
-
- /* Nonzero means do not delete comments within the directive.
- #define needs this when -traditional. */
- int keep_comments;
-
- old_linenum:
-
- limit = ip->buf + ip->length;
- unterminated = 0;
- already_output = 0;
- keep_comments = traditional && kt->type == T_DEFINE;
- /* #import is defined only in Objective C, or when on the NeXT. */
- if (kt->type == T_IMPORT
- && !(objc || lookup ((const U_CHAR *) "__NeXT__", -1, -1)))
- break;
-
- /* Find the end of this directive (first newline not backslashed
- and not in a string or comment).
- Set COPY_DIRECTIVE if the directive must be copied
- (it contains a backslash-newline or a comment). */
-
- buf = bp = after_ident;
- while (bp < limit) {
- register U_CHAR c = *bp++;
- switch (c) {
- case '\\':
- if (*bp == '\n') {
- ip->lineno++;
- copy_directive = 1;
- bp++;
- } else if (traditional && bp < limit)
- bp++;
- break;
-
- case '"':
- /* "..." is special for #include. */
- if (IS_INCLUDE_DIRECTIVE_TYPE (kt->type)) {
- while (bp < limit && *bp != '\n') {
- if (*bp == '"') {
- bp++;
- break;
- }
- if (*bp == '\\' && bp[1] == '\n') {
- ip->lineno++;
- copy_directive = 1;
- bp++;
- }
- bp++;
- }
- break;
- }
- /* Fall through. */
- case '\'':
- bp = skip_quoted_string (bp - 1, limit, ip->lineno, &ip->lineno, &copy_directive, &unterminated);
- /* Don't bother calling the directive if we already got an error
- message due to unterminated string. Skip everything and pretend
- we called the directive. */
- if (unterminated) {
- if (traditional) {
- /* Traditional preprocessing permits unterminated strings. */
- ip->bufp = bp;
- goto endloop1;
- }
- ip->bufp = bp;
- return 1;
- }
- break;
-
- /* <...> is special for #include. */
- case '<':
- if (! IS_INCLUDE_DIRECTIVE_TYPE (kt->type))
- break;
- while (bp < limit && *bp != '>' && *bp != '\n') {
- if (*bp == '\\' && bp[1] == '\n') {
- ip->lineno++;
- copy_directive = 1;
- bp++;
- }
- bp++;
- }
- break;
-
- case '/':
- if (*bp == '\\')
- newline_fix (bp);
- if (*bp == '*'
- || (cplusplus_comments && *bp == '/')) {
- U_CHAR *obp = bp - 1;
- ip->bufp = bp + 1;
- skip_to_end_of_comment (ip, &ip->lineno, 0);
- bp = ip->bufp;
- /* No need to copy the directive because of a comment at the end;
- just don't include the comment in the directive. */
- if (!put_out_comments) {
- U_CHAR *p;
- for (p = bp; *p == ' ' || *p == '\t'; p++)
- continue;
- if (*p == '\n') {
- bp = obp;
- goto endloop1;
- }
- }
- /* Don't remove the comments if -traditional. */
- if (! keep_comments)
- copy_directive++;
- }
- break;
-
- case '\f':
- case '\r':
- case '\v':
- if (pedantic)
- pedwarn_strange_white_space (c);
- break;
-
- case '\n':
- --bp; /* Point to the newline */
- ip->bufp = bp;
- goto endloop1;
- }
- }
- ip->bufp = bp;
-
- endloop1:
- resume_p = ip->bufp;
- /* BP is the end of the directive.
- RESUME_P is the next interesting data after the directive.
- A comment may come between. */
-
- /* If a directive should be copied through, and -C was given,
- pass it through before removing comments. */
- if (!no_output && put_out_comments
- && ((kt->type == T_DEFINE || kt->type == T_UNDEF)
- ? dump_macros == dump_definitions
- : IS_INCLUDE_DIRECTIVE_TYPE (kt->type) ? dump_includes
- : kt->type == T_PRAGMA)) {
- int len;
-
- /* Output directive name. */
- check_expand (op, kt->length + 2);
- /* Make sure # is at the start of a line */
- if (op->bufp > op->buf && op->bufp[-1] != '\n') {
- op->lineno++;
- *op->bufp++ = '\n';
- }
- *op->bufp++ = '#';
- bcopy (kt->name, op->bufp, kt->length);
- op->bufp += kt->length;
-
- /* Output arguments. */
- len = (bp - buf);
- check_expand (op, len);
- bcopy (buf, (char *) op->bufp, len);
- op->bufp += len;
- /* Take account of any (escaped) newlines just output. */
- while (--len >= 0)
- if (buf[len] == '\n')
- op->lineno++;
-
- already_output = &junk;
- } /* Don't we need a newline or #line? */
-
- if (copy_directive) {
- register U_CHAR *xp = buf;
- /* Need to copy entire directive into temp buffer before dispatching */
-
- /* room for directive plus some slop */
- cp = (U_CHAR *) alloca (2 * (bp - buf) + 5);
- buf = cp;
-
- /* Copy to the new buffer, deleting comments
- and backslash-newlines (and whitespace surrounding the latter
- if outside of char and string constants). */
-
- while (xp < bp) {
- register U_CHAR c = *xp++;
- *cp++ = c;
-
- switch (c) {
- case '\n':
- abort (); /* A bare newline should never part of the line. */
- break;
-
- /* <...> is special for #include. */
- case '<':
- if (! IS_INCLUDE_DIRECTIVE_TYPE (kt->type))
- break;
- while (xp < bp && c != '>') {
- c = *xp++;
- if (c == '\\' && xp < bp && *xp == '\n')
- xp++;
- else
- *cp++ = c;
- }
- break;
-
- case '\\':
- if (*xp == '\n') {
- xp++;
- cp--;
- if (cp != buf && is_hor_space[cp[-1]]) {
- while (cp - 1 != buf && is_hor_space[cp[-2]])
- cp--;
- SKIP_WHITE_SPACE (xp);
- } else if (is_hor_space[*xp]) {
- *cp++ = *xp++;
- SKIP_WHITE_SPACE (xp);
- }
- } else if (traditional && xp < bp) {
- *cp++ = *xp++;
- }
- break;
-
- case '\'':
- case '\"':
- {
- int backslash_newlines_p = 0;
-
- register const U_CHAR *bp1
- = skip_quoted_string (xp - 1, bp, ip->lineno,
- NULL_PTR, &backslash_newlines_p,
- NULL_PTR);
- if (backslash_newlines_p)
- while (xp != bp1)
- {
- /* With something like:
-
- #define X "a\
- b"
-
- we should still remove the backslash-newline
- pair as part of phase two. */
- if (xp[0] == '\\' && xp[1] == '\n')
- xp += 2;
- else
- *cp++ = *xp++;
- }
- else
- /* This is the same as the loop above, but taking
- advantage of the fact that we know there are no
- backslash-newline pairs. */
- while (xp != bp1)
- *cp++ = *xp++;
- }
- break;
-
- case '/':
- if (*xp == '*'
- || (cplusplus_comments && *xp == '/')) {
- ip->bufp = xp + 1;
- /* If we already copied the directive through,
- already_output != 0 prevents outputting comment now. */
- skip_to_end_of_comment (ip, already_output, 0);
- if (keep_comments)
- while (xp != ip->bufp)
- *cp++ = *xp++;
- /* Delete or replace the slash. */
- else if (traditional)
- cp--;
- else
- cp[-1] = ' ';
- xp = ip->bufp;
- }
- }
- }
-
- /* Null-terminate the copy. */
-
- *cp = 0;
- } else
- cp = bp;
-
- ip->bufp = resume_p;
-
- /* Some directives should be written out for cc1 to process,
- just as if they were not defined. And sometimes we're copying
- directives through. */
-
- if (!no_output && already_output == 0
- && ((kt->type == T_DEFINE || kt->type == T_UNDEF)
- ? (int) dump_names <= (int) dump_macros
- : IS_INCLUDE_DIRECTIVE_TYPE (kt->type) ? dump_includes
- : kt->type == T_PRAGMA)) {
- int len;
-
- /* Output directive name. */
- check_expand (op, kt->length + 1);
- *op->bufp++ = '#';
- bcopy (kt->name, (char *) op->bufp, kt->length);
- op->bufp += kt->length;
-
- if (kt->type == T_DEFINE && dump_macros == dump_names) {
- /* Output `#define name' only. */
- U_CHAR *xp = buf;
- U_CHAR *yp;
- SKIP_WHITE_SPACE (xp);
- yp = xp;
- while (is_idchar[*xp]) xp++;
- len = (xp - yp);
- check_expand (op, len + 1);
- *op->bufp++ = ' ';
- bcopy (yp, (char *) op->bufp, len);
- } else {
- /* Output entire directive. */
- len = (cp - buf);
- check_expand (op, len);
- bcopy (buf, (char *) op->bufp, len);
- }
- op->bufp += len;
- }
-
- /* Call the appropriate directive handler. buf now points to
- either the appropriate place in the input buffer, or to
- the temp buffer if it was necessary to make one. cp
- points to the first char after the contents of the (possibly
- copied) directive, in either case. */
- (*kt->func) (buf, cp, op, kt);
- check_expand (op, ip->length - (ip->bufp - ip->buf));
-
- return 1;
- }
- }
-
- /* It is deliberate that we don't warn about undefined directives.
- That is the responsibility of cc1. */
- return 0;
-}
-
-static struct tm *
-timestamp ()
-{
- static struct tm tmbuf;
- if (! tmbuf.tm_mday) {
- time_t t = time ((time_t *) 0);
- struct tm *tm = localtime (&t);
- if (tm)
- tmbuf = *tm;
- else {
- /* Use 0000-01-01 00:00:00 if local time is not available. */
- tmbuf.tm_year = -1900;
- tmbuf.tm_mday = 1;
- }
- }
- return &tmbuf;
-}
-
-static const char * const monthnames[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
-};
-
-/*
- * expand things like __FILE__. Place the expansion into the output
- * buffer *without* rescanning.
- */
-
-static void
-special_symbol (hp, op)
- HASHNODE *hp;
- FILE_BUF *op;
-{
- const char *buf;
- int i, len;
- int true_indepth;
- FILE_BUF *ip = NULL;
- struct tm *timebuf;
-
- int paren = 0; /* For special `defined' keyword */
-
- if (pcp_outfile && pcp_inside_if
- && hp->type != T_SPEC_DEFINED && hp->type != T_CONST)
- error ("Predefined macro `%s' used inside `#if' during precompilation",
- hp->name);
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
- if (ip == NULL) {
- error ("cccp error: not in any file?!");
- return; /* the show must go on */
- }
-
- switch (hp->type) {
- case T_FILE:
- case T_BASE_FILE:
- {
- FILE_BUF *p = hp->type == T_FILE ? ip : &instack[0];
- const char *string = p->nominal_fname;
-
- if (string)
- {
- size_t string_len = p->nominal_fname_len;
- char *newbuf = (char *) alloca (3 + 4 * string_len);
- quote_string (newbuf, string, string_len);
- buf = newbuf;
- }
- else
- buf = "\"\"";
-
- break;
- }
-
- case T_INCLUDE_LEVEL:
- {
- /* Eight bytes ought to be more than enough */
- char *newbuf = (char *) alloca (8);
- true_indepth = 0;
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL)
- true_indepth++;
- sprintf (newbuf, "%d", true_indepth - 1);
- buf = newbuf;
- }
- break;
-
- case T_VERSION:
- {
- char *newbuf = (char *) alloca (3 + strlen (version_string));
- sprintf (newbuf, "\"%s\"", version_string);
- buf = newbuf;
- }
- break;
-
-#ifndef NO_BUILTIN_SIZE_TYPE
- case T_SIZE_TYPE:
- buf = SIZE_TYPE;
- break;
-#endif
-
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
- case T_PTRDIFF_TYPE:
- buf = PTRDIFF_TYPE;
- break;
-#endif
-
-#ifndef NO_BUILTIN_WCHAR_TYPE
- case T_WCHAR_TYPE:
- buf = wchar_type;
- break;
-#endif
-
- case T_USER_LABEL_PREFIX_TYPE:
- buf = user_label_prefix;
- break;
-
- case T_REGISTER_PREFIX_TYPE:
- buf = REGISTER_PREFIX;
- break;
-
- case T_IMMEDIATE_PREFIX_TYPE:
- buf = IMMEDIATE_PREFIX;
- break;
-
- case T_CONST:
- buf = hp->value.cpval;
-#ifdef STDC_0_IN_SYSTEM_HEADERS
- if (ip->system_header_p
- && hp->length == 8 && bcmp (hp->name, "__STDC__", 8) == 0
- && !lookup ((const U_CHAR *) "__STRICT_ANSI__", -1, -1))
- buf = "0";
-#endif
- if (pcp_inside_if && pcp_outfile)
- /* Output a precondition for this macro use */
- fprintf (pcp_outfile, "#define %s %s\n", hp->name, buf);
- break;
-
- case T_SPECLINE:
- {
- char *newbuf = (char *) alloca (10);
- sprintf (newbuf, "%d", ip->lineno);
- buf = newbuf;
- }
- break;
-
- case T_DATE:
- case T_TIME:
- {
- char *newbuf = (char *) alloca (20);
- timebuf = timestamp ();
- if (hp->type == T_DATE)
- sprintf (newbuf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
- timebuf->tm_mday, timebuf->tm_year + 1900);
- else
- sprintf (newbuf, "\"%02d:%02d:%02d\"", timebuf->tm_hour,
- timebuf->tm_min, timebuf->tm_sec);
- buf = newbuf;
- }
- break;
-
- case T_SPEC_DEFINED:
- buf = " 0 "; /* Assume symbol is not defined */
- ip = &instack[indepth];
- SKIP_WHITE_SPACE (ip->bufp);
- if (*ip->bufp == '(') {
- paren++;
- ip->bufp++; /* Skip over the paren */
- SKIP_WHITE_SPACE (ip->bufp);
- }
-
- if (!is_idstart[*ip->bufp])
- goto oops;
- if (ip->bufp[0] == 'L' && (ip->bufp[1] == '\'' || ip->bufp[1] == '"'))
- goto oops;
- if ((hp = lookup (ip->bufp, -1, -1))) {
- if (pcp_outfile && pcp_inside_if
- && (hp->type == T_CONST
- || (hp->type == T_MACRO && hp->value.defn->predefined)))
- /* Output a precondition for this macro use. */
- fprintf (pcp_outfile, "#define %s\n", hp->name);
- if (hp->type == T_POISON) {
- error("attempt to use poisoned `%s'.", hp->name);
- buf = " 0 ";
- } else {
- buf = " 1 ";
- }
- }
- else
- if (pcp_outfile && pcp_inside_if) {
- /* Output a precondition for this macro use */
- U_CHAR *cp = ip->bufp;
- fprintf (pcp_outfile, "#undef ");
- while (is_idchar[*cp]) /* Ick! */
- fputc (*cp++, pcp_outfile);
- putc ('\n', pcp_outfile);
- }
- while (is_idchar[*ip->bufp])
- ++ip->bufp;
- SKIP_WHITE_SPACE (ip->bufp);
- if (paren) {
- if (*ip->bufp != ')')
- goto oops;
- ++ip->bufp;
- }
- break;
-
- case T_POISON:
- error("attempt to use poisoned `%s'.", hp->name);
- buf = " 0 "; /* Consider poisoned symbol to not be defined */
- break;
-
-oops:
-
- error ("`defined' without an identifier");
- break;
-
- default:
- error ("cccp error: invalid special hash type"); /* time for gdb */
- abort ();
- }
- len = strlen (buf);
- check_expand (op, len);
- bcopy (buf, (char *) op->bufp, len);
- op->bufp += len;
-
- return;
-}
-
-
-/* Routines to handle #directives */
-
-/* Handle #include and #import.
- This function expects to see "fname" or <fname> on the input. */
-
-static int
-do_include (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- const U_CHAR *importing =
- keyword->type == T_IMPORT ? (const U_CHAR *) "" : (const U_CHAR *) 0;
- int skip_dirs = (keyword->type == T_INCLUDE_NEXT);
- static int import_warning = 0;
- char *fname; /* Dynamically allocated fname buffer */
- char *pcftry;
- char *pcfname;
- char *fbeg, *fend; /* Beginning and end of fname */
- U_CHAR *fin;
-
- struct file_name_list *search_start = include; /* Chain of dirs to search */
- struct file_name_list *dsp; /* First in chain, if #include "..." */
- struct file_name_list *searchptr = 0;
- size_t flen;
-
- int f = -3; /* file number */
- struct include_file *inc = 0;
-
- int retried = 0; /* Have already tried macro
- expanding the include line*/
- int angle_brackets = 0; /* 0 for "...", 1 for <...> */
-#ifdef VMS
- int vaxc_include = 0; /* 1 for token without punctuation */
-#endif
- int pcf = -1;
- char *pcfbuf;
- const char *pcfbuflimit;
- int pcfnum;
-
- if (pedantic && !instack[indepth].system_header_p)
- {
- if (importing)
- pedwarn ("ANSI C does not allow `#import'");
- if (skip_dirs)
- pedwarn ("ANSI C does not allow `#include_next'");
- }
-
- if (importing && warn_import && !inhibit_warnings
- && !instack[indepth].system_header_p && !import_warning) {
- import_warning = 1;
- warning ("using `#import' is not recommended");
- notice ("The fact that a certain header file need not be processed more than once\n\
-should be indicated in the header file, not where it is used.\n\
-The best way to do this is with a conditional of this form:\n\
-\n\
- #ifndef _FOO_H_INCLUDED\n\
- #define _FOO_H_INCLUDED\n\
- ... <real contents of file> ...\n\
- #endif /* Not _FOO_H_INCLUDED */\n\
-\n\
-Then users can use `#include' any number of times.\n\
-GNU C automatically avoids processing the file more than once\n\
-when it is equipped with such a conditional.\n");
- }
-
-get_filename:
-
- fin = buf;
- SKIP_WHITE_SPACE (fin);
- /* Discard trailing whitespace so we can easily see
- if we have parsed all the significant chars we were given. */
- while (limit != fin && is_hor_space[limit[-1]]) limit--;
- fbeg = fend = (char *) alloca (limit - fin);
-
- switch (*fin++) {
- case '\"':
- {
- FILE_BUF *fp;
- /* Copy the operand text, concatenating the strings. */
- {
- for (;;) {
- for (;;) {
- if (fin == limit)
- goto invalid_include_file_name;
- *fend = *fin++;
- if (*fend == '"')
- break;
- fend++;
- }
- if (fin == limit)
- break;
- /* If not at the end, there had better be another string. */
- /* Skip just horiz space, and don't go past limit. */
- while (fin != limit && is_hor_space[*fin]) fin++;
- if (fin != limit && *fin == '\"')
- fin++;
- else
- goto fail;
- }
- }
-
- /* We have "filename". Figure out directory this source
- file is coming from and put it on the front of the list. */
-
- /* If -I- was specified, don't search current dir, only spec'd ones. */
- if (ignore_srcdir) break;
-
- for (fp = &instack[indepth]; fp >= instack; fp--)
- {
- int n;
-
- if ((fp->nominal_fname) != NULL) {
- char *nam;
- /* Found a named file. Figure out dir of the file,
- and put it in front of the search list. */
- dsp = ((struct file_name_list *)
- alloca (sizeof (struct file_name_list)
- + fp->nominal_fname_len));
- strcpy (dsp->fname, fp->nominal_fname);
- simplify_filename (dsp->fname);
- nam = base_name (dsp->fname);
- *nam = 0;
-#ifdef VMS
- /* for hack_vms_include_specification(), a local
- dir specification must start with "./" on VMS. */
- if (nam == dsp->fname)
- {
- *nam++ = '.';
- *nam++ = '/';
- *nam = 0;
- }
-#endif
- /* But for efficiency's sake, do not insert the dir
- if it matches the search list's first dir. */
- dsp->next = search_start;
- if (!search_start || strcmp (dsp->fname, search_start->fname)) {
- search_start = dsp;
- n = nam - dsp->fname;
- if (n + INCLUDE_LEN_FUDGE > max_include_len)
- max_include_len = n + INCLUDE_LEN_FUDGE;
- }
- dsp[0].got_name_map = 0;
- break;
- }
- }
- break;
- }
-
- case '<':
- while (fin != limit && *fin != '>')
- *fend++ = *fin++;
- if (*fin == '>' && fin + 1 == limit) {
- angle_brackets = 1;
- /* If -I-, start with the first -I dir after the -I-. */
- search_start = first_bracket_include;
- break;
- }
- goto fail;
-
- default:
-#ifdef VMS
- /*
- * Support '#include xyz' like VAX-C to allow for easy use of all the
- * decwindow include files. It defaults to '#include <xyz.h>' (so the
- * code from case '<' is repeated here) and generates a warning.
- * (Note: macro expansion of `xyz' takes precedence.)
- */
- /* Note: The argument of ISALPHA() can be evaluated twice, so do
- the pre-decrement outside of the macro. */
- if (retried && (--fin, ISALPHA(*(U_CHAR *) (fin)))) {
- while (fin != limit && (!ISSPACE(*fin)))
- *fend++ = *fin++;
- warning ("VAX-C-style include specification found, use '#include <filename.h>' !");
- vaxc_include = 1;
- if (fin == limit) {
- angle_brackets = 1;
- /* If -I-, start with the first -I dir after the -I-. */
- search_start = first_bracket_include;
- break;
- }
- }
-#endif
-
- fail:
- if (! retried) {
- /* Expand buffer and then remove any newline markers.
- We can't just tell expand_to_temp_buffer to omit the markers,
- since it would put extra spaces in include file names. */
- U_CHAR *src;
- int errors_before_expansion = errors;
- FILE_BUF trybuf;
-
- trybuf = expand_to_temp_buffer (buf, limit, 1, 0);
- if (errors != errors_before_expansion) {
- free (trybuf.buf);
- goto invalid_include_file_name;
- }
- src = trybuf.buf;
- buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
- limit = buf;
- while (src != trybuf.bufp) {
- switch ((*limit++ = *src++)) {
- case '\n':
- limit--;
- src++;
- break;
-
- case '\'':
- case '\"':
- {
- const U_CHAR *src1 = skip_quoted_string (src - 1, trybuf.bufp, 0,
- NULL_PTR, NULL_PTR, NULL_PTR);
- while (src != src1)
- *limit++ = *src++;
- }
- break;
- }
- }
- *limit = 0;
- free (trybuf.buf);
- retried = 1;
- goto get_filename;
- }
-
- invalid_include_file_name:
- error ("`#%s' expects \"FILENAME\" or <FILENAME>", keyword->name);
- return 0;
- }
-
- /* For #include_next, skip in the search path
- past the dir in which the containing file was found. */
- if (skip_dirs) {
- FILE_BUF *fp;
- for (fp = &instack[indepth]; fp >= instack; fp--)
- if (fp->fname != NULL) {
- /* fp->dir is null if the containing file was specified
- with an absolute file name. In that case, don't skip anything. */
- if (fp->dir)
- search_start = fp->dir->next;
- break;
- }
- }
-
- *fend = 0;
- flen = simplify_filename (fbeg);
-
- if (flen == 0)
- {
- error ("empty file name in `#%s'", keyword->name);
- return 0;
- }
-
- /* Allocate this permanently, because it gets stored in the definitions
- of macros. */
- fname = xmalloc (max_include_len + flen + 1);
- /* + 1 above for terminating null. */
-
- system_include_depth += angle_brackets;
-
- /* If specified file name is absolute, just open it. */
-
- if (absolute_filename (fbeg)) {
- strcpy (fname, fbeg);
- f = open_include_file (fname, NULL_PTR, importing, &inc);
- } else {
-
- struct bypass_dir {
- struct bypass_dir *next;
- char *fname;
- struct file_name_list *searchptr;
- } **bypass_slot = 0;
-
- /* Search directory path, trying to open the file.
- Copy each filename tried into FNAME. */
-
- for (searchptr = search_start; searchptr; searchptr = searchptr->next) {
-
- if (searchptr == first_bracket_include) {
- /* Go to bypass directory if we know we've seen this file before. */
- static struct bypass_dir *bypass_hashtab[INCLUDE_HASHSIZE];
- struct bypass_dir *p;
- bypass_slot = &bypass_hashtab[hashf ((U_CHAR *) fbeg, flen,
- INCLUDE_HASHSIZE)];
- for (p = *bypass_slot; p; p = p->next)
- if (!strcmp (fbeg, p->fname)) {
- searchptr = p->searchptr;
- bypass_slot = 0;
- break;
- }
- }
-
-#ifdef VMS
- /* Change this 1/2 Unix 1/2 VMS file specification into a
- full VMS file specification */
- if (searchptr->fname[0])
- {
- strcpy (fname, searchptr->fname);
- if (fname[strlen (fname) - 1] == ':')
- {
- char *slashp;
- slashp = strchr (fbeg, '/');
-
- /* start at root-dir of logical device if no path given. */
- if (slashp == 0)
- strcat (fname, "[000000]");
- }
- strcat (fname, fbeg);
-
- /* Fix up the filename */
- hack_vms_include_specification (fname, vaxc_include);
- }
- else
- {
- /* This is a normal VMS filespec, so use it unchanged. */
- strcpy (fname, fbeg);
- /* if it's '#include filename', add the missing .h */
- if (vaxc_include && index(fname,'.')==NULL)
- strcat (fname, ".h");
- }
-#else
- strcpy (fname, searchptr->fname);
- strcat (fname, fbeg);
-#endif /* VMS */
- f = open_include_file (fname, searchptr, importing, &inc);
- if (f != -1) {
- if (bypass_slot && searchptr != first_bracket_include) {
- /* This is the first time we found this include file,
- and we found it after first_bracket_include.
- Record its location so that we can bypass to here next time. */
- struct bypass_dir *p
- = (struct bypass_dir *) xmalloc (sizeof (struct bypass_dir));
- p->next = *bypass_slot;
- p->fname = fname + strlen (searchptr->fname);
- p->searchptr = searchptr;
- *bypass_slot = p;
- }
- break;
- }
-#ifdef VMS
- /* Our VMS hacks can produce invalid filespecs, so don't worry
- about errors other than EACCES. */
- if (errno == EACCES)
- break;
-#else
- if (errno != ENOENT && errno != ENOTDIR)
- break;
-#endif
- }
- }
-
-
- if (f < 0) {
-
- if (f == -2) {
- /* The file was already included. */
-
- /* If generating dependencies and -MG was specified, we assume missing
- files are leaf files, living in the same directory as the source file
- or other similar place; these missing files may be generated from
- other files and may not exist yet (eg: y.tab.h). */
- } else if (print_deps_missing_files
- && (system_include_depth != 0) < print_deps)
- {
- /* If it was requested as a system header file,
- then assume it belongs in the first place to look for such. */
- if (angle_brackets)
- {
- if (search_start) {
- char *p = (char *) alloca (strlen (search_start->fname)
- + strlen (fbeg) + 1);
- strcpy (p, search_start->fname);
- strcat (p, fbeg);
- deps_output (p, ' ');
- }
- }
- else
- {
- /* Otherwise, omit the directory, as if the file existed
- in the directory with the source. */
- deps_output (fbeg, ' ');
- }
- }
- /* If -M was specified, and this header file won't be added to the
- dependency list, then don't count this as an error, because we can
- still produce correct output. Otherwise, we can't produce correct
- output, because there may be dependencies we need inside the missing
- file, and we don't know what directory this missing file exists in. */
- else if (0 < print_deps && print_deps <= (system_include_depth != 0))
- warning ("No include path in which to find %s", fbeg);
- else if (f != -3)
- error_from_errno (fbeg);
- else
- error ("No include path in which to find %s", fbeg);
-
- } else {
-
- /* Actually process the file. */
-
- pcftry = (char *) alloca (strlen (fname) + 30);
- pcfbuf = 0;
- pcfnum = 0;
-
- if (!no_precomp)
- {
- do {
- sprintf (pcftry, "%s%d", fname, pcfnum++);
-
- pcf = open (pcftry, O_RDONLY, 0666);
- if (pcf != -1)
- {
- struct stat s;
-
- if (fstat (pcf, &s) != 0)
- pfatal_with_name (pcftry);
- if (! INO_T_EQ (inc->st.st_ino, s.st_ino)
- || inc->st.st_dev != s.st_dev)
- {
- pcfbuf = check_precompiled (pcf, &s, fname, &pcfbuflimit);
- /* Don't need it any more. */
- close (pcf);
- }
- else
- {
- /* Don't need it at all. */
- close (pcf);
- break;
- }
- }
- } while (pcf != -1 && !pcfbuf);
- }
-
- /* Actually process the file */
- if (pcfbuf) {
- pcfname = xstrdup (pcftry);
- pcfinclude ((U_CHAR *) pcfbuf, (U_CHAR *) fname, op);
- }
- else
- finclude (f, inc, op, is_system_include (fname), searchptr);
- }
-
- system_include_depth -= angle_brackets;
-
- return 0;
-}
-
-/* Return nonzero if the given FILENAME is an absolute pathname which
- designates a file within one of the known "system" include file
- directories. We assume here that if the given FILENAME looks like
- it is the name of a file which resides either directly in a "system"
- include file directory, or within any subdirectory thereof, then the
- given file must be a "system" include file. This function tells us
- if we should suppress pedantic errors/warnings for the given FILENAME.
-
- The value is 2 if the file is a C-language system header file
- for which C++ should (on most systems) assume `extern "C"'. */
-
-static int
-is_system_include (filename)
- register const char *filename;
-{
- struct file_name_list *searchptr;
-
- for (searchptr = first_system_include; searchptr;
- searchptr = searchptr->next)
- if (! strncmp (searchptr->fname, filename, strlen (searchptr->fname)))
- return searchptr->c_system_include_path + 1;
- return 0;
-}
-
-/* Yield the non-directory suffix of a file name. */
-
-static char *
-base_name (fname)
- const char *fname;
-{
- const char *s = fname;
- const char *p;
-#if defined (__MSDOS__) || defined (_WIN32)
- if (ISALPHA (s[0]) && s[1] == ':') s += 2;
-#endif
-#ifdef VMS
- if ((p = rindex (s, ':'))) s = p + 1; /* Skip device. */
- if ((p = rindex (s, ']'))) s = p + 1; /* Skip directory. */
- if ((p = rindex (s, '>'))) s = p + 1; /* Skip alternate (int'n'l) dir. */
- if (s != fname)
- return (char *) s;
-#endif
- if ((p = rindex (s, '/'))) s = p + 1;
-#ifdef DIR_SEPARATOR
- if ((p = rindex (s, DIR_SEPARATOR))) s = p + 1;
-#endif
- return (char *) s;
-}
-
-/* Yield nonzero if FILENAME is absolute (i.e. not relative). */
-
-static int
-absolute_filename (filename)
- const char *filename;
-{
-#if defined (__MSDOS__) \
- || (defined (_WIN32) && !defined (__CYGWIN__) && !defined (_UWIN))
- if (ISALPHA (filename[0]) && filename[1] == ':') filename += 2;
-#endif
-#if defined (__CYGWIN__)
- /* At present, any path that begins with a drive spec is absolute. */
- if (ISALPHA (filename[0]) && filename[1] == ':') return 1;
-#endif
-#ifdef VMS
- if (index (filename, ':') != 0) return 1;
-#endif
- if (filename[0] == '/') return 1;
-#ifdef DIR_SEPARATOR
- if (filename[0] == DIR_SEPARATOR) return 1;
-#endif
- return 0;
-}
-
-/* Returns whether or not a given character is a directory separator.
- Used by simplify_filename. */
-static inline int is_dir_separator PARAMS ((int));
-
-static inline
-int
-is_dir_separator(ch)
- char ch;
-{
- return (ch == DIR_SEPARATOR)
-#if defined (DIR_SEPARATOR_2)
- || (ch == DIR_SEPARATOR_2)
-#endif
- ;
-}
-
-/* Remove unnecessary characters from FILENAME in place,
- to avoid unnecessary filename aliasing.
- Return the length of the resulting string.
-
- Do only the simplifications allowed by Posix.
- It is OK to miss simplifications on non-Posix hosts,
- since this merely leads to suboptimal results. */
-
-static size_t
-simplify_filename (filename)
- char *filename;
-{
- register char *from = filename;
- register char *to = filename;
- char *to0;
-
- /* Remove redundant initial /s. */
- if (is_dir_separator (*from))
- {
- *to++ = DIR_SEPARATOR;
- if (is_dir_separator (*++from))
- {
- if (is_dir_separator (*++from))
- {
- /* 3 or more initial /s are equivalent to 1 /. */
- while (is_dir_separator (*++from))
- continue;
- }
- else
- {
- /* On some hosts // differs from /; Posix allows this. */
- *to++ = DIR_SEPARATOR;
- }
- }
- }
-
- to0 = to;
-
- for (;;)
- {
-#ifndef VMS
- if (from[0] == '.' && from[1] == '/')
- from += 2;
- else
-#endif
- {
- /* Copy this component and trailing DIR_SEPARATOR, if any. */
- while (!is_dir_separator (*to++ = *from++))
- {
- if (!to[-1])
- {
- /* Trim . component at end of nonempty name. */
- to -= filename <= to - 3 && to[-3] == DIR_SEPARATOR && to[-2] == '.';
-
- /* Trim unnecessary trailing /s. */
- while (to0 < --to && to[-1] == DIR_SEPARATOR)
- continue;
-
- *to = 0;
- return to - filename;
- }
- }
-#if defined(DIR_SEPARATOR_2)
- /* Simplify to one directory separator. */
- to[-1] = DIR_SEPARATOR;
-#endif
- }
-
- /* Skip /s after a /. */
- while (is_dir_separator (*from))
- from++;
- }
-}
-
-/* The file_name_map structure holds a mapping of file names for a
- particular directory. This mapping is read from the file named
- FILE_NAME_MAP_FILE in that directory. Such a file can be used to
- map filenames on a file system with severe filename restrictions,
- such as DOS. The format of the file name map file is just a series
- of lines with two tokens on each line. The first token is the name
- to map, and the second token is the actual name to use. */
-
-struct file_name_map
-{
- struct file_name_map *map_next;
- char *map_from;
- char *map_to;
-};
-
-#define FILE_NAME_MAP_FILE "header.gcc"
-
-/* Read a space delimited string of unlimited length from a stdio
- file. */
-
-static char *
-read_filename_string (ch, f)
- int ch;
- FILE *f;
-{
- char *alloc, *set;
- int len;
-
- len = 20;
- set = alloc = xmalloc (len + 1);
- if (! is_space[ch])
- {
- *set++ = ch;
- while ((ch = getc (f)) != EOF && ! is_space[ch])
- {
- if (set - alloc == len)
- {
- len *= 2;
- alloc = xrealloc (alloc, len + 1);
- set = alloc + len / 2;
- }
- *set++ = ch;
- }
- }
- *set = '\0';
- ungetc (ch, f);
- return alloc;
-}
-
-/* Read the file name map file for DIRNAME.
- If DIRNAME is empty, read the map file for the working directory;
- otherwise DIRNAME must end in '/'. */
-
-static struct file_name_map *
-read_name_map (dirname)
- const char *dirname;
-{
- /* This structure holds a linked list of file name maps, one per
- directory. */
- struct file_name_map_list
- {
- struct file_name_map_list *map_list_next;
- char *map_list_name;
- struct file_name_map *map_list_map;
- };
- static struct file_name_map_list *map_list;
- register struct file_name_map_list *map_list_ptr;
- char *name;
- FILE *f;
- size_t dirlen;
-
- for (map_list_ptr = map_list; map_list_ptr;
- map_list_ptr = map_list_ptr->map_list_next)
- if (! strcmp (map_list_ptr->map_list_name, dirname))
- return map_list_ptr->map_list_map;
-
- map_list_ptr = ((struct file_name_map_list *)
- xmalloc (sizeof (struct file_name_map_list)));
- map_list_ptr->map_list_name = xstrdup (dirname);
- map_list_ptr->map_list_map = NULL;
-
- dirlen = strlen (dirname);
- name = (char *) alloca (dirlen + strlen (FILE_NAME_MAP_FILE) + 1);
- strcpy (name, dirname);
- strcat (name, FILE_NAME_MAP_FILE);
- f = fopen (name, "r");
- if (!f)
- map_list_ptr->map_list_map = NULL;
- else
- {
- int ch;
-
- while ((ch = getc (f)) != EOF)
- {
- char *from, *to;
- struct file_name_map *ptr;
- size_t tolen;
-
- if (is_space[ch])
- continue;
- from = read_filename_string (ch, f);
- while ((ch = getc (f)) != EOF && is_hor_space[ch])
- ;
- to = read_filename_string (ch, f);
-
- simplify_filename (from);
- tolen = simplify_filename (to);
-
- ptr = ((struct file_name_map *)
- xmalloc (sizeof (struct file_name_map)));
- ptr->map_from = from;
-
- /* Make the real filename absolute. */
- if (absolute_filename (to))
- ptr->map_to = to;
- else
- {
- ptr->map_to = xmalloc (dirlen + tolen + 1);
- strcpy (ptr->map_to, dirname);
- strcat (ptr->map_to, to);
- free (to);
- }
-
- ptr->map_next = map_list_ptr->map_list_map;
- map_list_ptr->map_list_map = ptr;
-
- while ((ch = getc (f)) != '\n')
- if (ch == EOF)
- break;
- }
- fclose (f);
- }
-
- map_list_ptr->map_list_next = map_list;
- map_list = map_list_ptr;
-
- return map_list_ptr->map_list_map;
-}
-
-/* Try to open include file FILENAME. SEARCHPTR is the directory
- being tried from the include file search path.
- IMPORTING is "" if we are importing, null otherwise.
- Return -2 if found, either a matching name or a matching inode.
- Otherwise, open the file and return a file descriptor if successful
- or -1 if unsuccessful.
- Unless unsuccessful, put a descriptor of the included file into *PINC.
- This function maps filenames on file systems based on information read by
- read_name_map. */
-
-static int
-open_include_file (filename, searchptr, importing, pinc)
- char *filename;
- struct file_name_list *searchptr;
- const U_CHAR *importing;
- struct include_file **pinc;
-{
- char *fname = remap ? remap_include_file (filename, searchptr) : filename;
- int fd = -2;
-
- /* Look up FNAME in include_hashtab. */
- struct include_file **phead = &include_hashtab[hashf ((U_CHAR *) fname,
- strlen (fname),
- INCLUDE_HASHSIZE)];
- struct include_file *inc, *head = *phead;
- for (inc = head; inc; inc = inc->next)
- if (!strcmp (fname, inc->fname))
- break;
-
- if (!inc
- || ! inc->control_macro
- || (inc->control_macro[0] && ! lookup (inc->control_macro, -1, -1))) {
-
- fd = open (fname, O_RDONLY, 0);
-
- if (fd < 0)
- {
-#ifdef VMS
- /* if #include <dir/file> fails, try again with hacked spec. */
- if (!hack_vms_include_specification (fname, 0))
- return fd;
- fd = open (fname, O_RDONLY, 0);
- if (fd < 0)
-#endif
- return fd;
- }
-
- if (!inc) {
- /* FNAME was not in include_hashtab; insert a new entry. */
- inc = (struct include_file *) xmalloc (sizeof (struct include_file));
- inc->next = head;
- inc->fname = fname;
- inc->control_macro = 0;
- inc->deps_output = 0;
- if (fstat (fd, &inc->st) != 0)
- pfatal_with_name (fname);
- *phead = inc;
-
- /* Look for another file with the same inode and device. */
- if (lookup_ino_include (inc)
- && inc->control_macro
- && (!inc->control_macro[0] || lookup (inc->control_macro, -1, -1))) {
- close (fd);
- fd = -2;
- }
- }
-
- /* For -M, add this file to the dependencies. */
- if (! inc->deps_output && (system_include_depth != 0) < print_deps) {
- inc->deps_output = 1;
- deps_output (fname, ' ');
- }
-
- /* Handle -H option. */
- if (print_include_names)
- fprintf (stderr, "%*s%s\n", indepth, "", fname);
- }
-
- if (importing)
- inc->control_macro = importing;
-
- *pinc = inc;
- return fd;
-}
-
-/* Return the remapped name of the include file FILENAME.
- SEARCHPTR is the directory being tried from the include file path. */
-
-static char *
-remap_include_file (filename, searchptr)
- char *filename;
- struct file_name_list *searchptr;
-{
- register struct file_name_map *map;
- register const char *from;
-
- if (searchptr)
- {
- if (! searchptr->got_name_map)
- {
- searchptr->name_map = read_name_map (searchptr->fname);
- searchptr->got_name_map = 1;
- }
-
- /* Check the mapping for the directory we are using. */
- from = filename + strlen (searchptr->fname);
- for (map = searchptr->name_map; map; map = map->map_next)
- if (! strcmp (map->map_from, from))
- return map->map_to;
- }
-
- from = base_name (filename);
-
- if (from != filename || !searchptr)
- {
- /* Try to find a mapping file for the particular directory we are
- looking in. Thus #include <sys/types.h> will look up sys/types.h
- in /usr/include/header.gcc and look up types.h in
- /usr/include/sys/header.gcc. */
-
- char *dir = (char *) alloca (from - filename + 1);
- bcopy (filename, dir, from - filename);
- dir[from - filename] = '\0';
-
- for (map = read_name_map (dir); map; map = map->map_next)
- if (! strcmp (map->map_from, from))
- return map->map_to;
- }
-
- return filename;
-}
-
-/* Insert INC into the include file table, hashed by device and inode number.
- If a file with different name but same dev+ino was already in the table,
- return 1 and set INC's control macro to the already-known macro. */
-
-static int
-lookup_ino_include (inc)
- struct include_file *inc;
-{
- int hash = ((unsigned) (inc->st.st_dev + INO_T_HASH (inc->st.st_ino))
- % INCLUDE_HASHSIZE);
- struct include_file *i = include_ino_hashtab[hash];
- inc->next_ino = i;
- include_ino_hashtab[hash] = inc;
-
- for (; i; i = i->next_ino)
- if (INO_T_EQ (inc->st.st_ino, i->st.st_ino)
- && inc->st.st_dev == i->st.st_dev) {
- inc->control_macro = i->control_macro;
- return 1;
- }
-
- return 0;
-}
-
-/* Process file descriptor F, which corresponds to include file INC,
- with output to OP.
- SYSTEM_HEADER_P is 1 if this file resides in any one of the known
- "system" include directories (as decided by the `is_system_include'
- function above).
- DIRPTR is the link in the dir path through which this file was found,
- or 0 if the file name was absolute. */
-
-static void
-finclude (f, inc, op, system_header_p, dirptr)
- int f;
- struct include_file *inc;
- FILE_BUF *op;
- int system_header_p;
- struct file_name_list *dirptr;
-{
- char *fname = inc->fname;
- int i;
- FILE_BUF *fp; /* For input stack frame */
- int missing_newline = 0;
-
- CHECK_DEPTH (return;);
-
- fp = &instack[indepth + 1];
- bzero ((char *) fp, sizeof (FILE_BUF));
- fp->nominal_fname = fp->fname = fname;
- fp->nominal_fname_len = strlen (fname);
- fp->inc = inc;
- fp->length = 0;
- fp->lineno = 1;
- fp->if_stack = if_stack;
- fp->system_header_p = system_header_p;
- fp->dir = dirptr;
-
- if (S_ISREG (inc->st.st_mode)) {
- size_t s = (size_t) inc->st.st_size;
- if (s != inc->st.st_size || s + 2 < s)
- memory_full ();
- fp->buf = (U_CHAR *) xmalloc (s + 2);
- fp->bufp = fp->buf;
-
- /* Read the file contents, knowing that s is an upper bound
- on the number of bytes we can read. */
- fp->length = safe_read (f, (char *) fp->buf, s);
- if (fp->length < 0) goto nope;
- }
- else if (S_ISDIR (inc->st.st_mode)) {
- error ("directory `%s' specified in #include", fname);
- close (f);
- return;
- } else {
- /* Cannot count its file size before reading.
- First read the entire file into heap and
- copy them into buffer on stack. */
-
- int bsize = 2000;
- int st_size = 0;
-
- fp->buf = (U_CHAR *) xmalloc (bsize + 2);
-
- for (;;) {
- i = safe_read (f, (char *) fp->buf + st_size, bsize - st_size);
- if (i < 0)
- goto nope; /* error! */
- st_size += i;
- if (st_size != bsize)
- break; /* End of file */
- bsize *= 2;
- fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
- }
- fp->bufp = fp->buf;
- fp->length = st_size;
- }
-
- if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
- /* Backslash-newline at end is not good enough. */
- || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
- fp->buf[fp->length++] = '\n';
- missing_newline = 1;
- }
- fp->buf[fp->length] = '\0';
-
- /* Close descriptor now, so nesting does not use lots of descriptors. */
- close (f);
-
- /* Must do this before calling trigraph_pcp, so that the correct file name
- will be printed in warning messages. */
-
- indepth++;
- input_file_stack_tick++;
-
- if (!no_trigraphs)
- trigraph_pcp (fp);
-
- if (warn_white_space)
- check_white_space (fp);
-
- output_line_directive (fp, op, 0, enter_file);
- rescan (op, 0);
-
- if (missing_newline)
- fp->lineno--;
-
- if (pedantic && missing_newline)
- pedwarn ("file does not end in newline");
-
- indepth--;
- input_file_stack_tick++;
- output_line_directive (&instack[indepth], op, 0, leave_file);
- free (fp->buf);
- return;
-
- nope:
-
- perror_with_name (fname);
- close (f);
- free (fp->buf);
-}
-
-/* Record that inclusion of the include file INC
- should be controlled by the macro named MACRO_NAME.
- This means that trying to include the file again
- will do something if that macro is defined. */
-
-static void
-record_control_macro (inc, macro_name)
- struct include_file *inc;
- const U_CHAR *macro_name;
-{
- if (!inc->control_macro || inc->control_macro[0])
- inc->control_macro = macro_name;
-}
-
-/* Load the specified precompiled header into core, and verify its
- preconditions. PCF indicates the file descriptor to read, which must
- be a regular file. *ST is its file status.
- FNAME indicates the file name of the original header.
- *LIMIT will be set to an address one past the end of the file.
- If the preconditions of the file are not satisfied, the buffer is
- freed and we return 0. If the preconditions are satisfied, return
- the address of the buffer following the preconditions. The buffer, in
- this case, should never be freed because various pieces of it will
- be referred to until all precompiled strings are output at the end of
- the run. */
-
-static char *
-check_precompiled (pcf, st, fname, limit)
- int pcf;
- struct stat *st;
- const char *fname ATTRIBUTE_UNUSED;
- const char **limit;
-{
- int length = 0;
- char *buf;
- char *cp;
-
- if (pcp_outfile)
- return 0;
-
- if (S_ISREG (st->st_mode))
- {
- size_t s = (size_t) st->st_size;
- if (s != st->st_size || s + 2 < s)
- memory_full ();
- buf = xmalloc (s + 2);
- length = safe_read (pcf, buf, s);
- if (length < 0)
- goto nope;
- }
- else
- abort ();
-
- if (length > 0 && buf[length-1] != '\n')
- buf[length++] = '\n';
- buf[length] = '\0';
-
- *limit = buf + length;
-
- /* File is in core. Check the preconditions. */
- if (!check_preconditions (buf))
- goto nope;
- for (cp = buf; *cp; cp++)
- ;
-#ifdef DEBUG_PCP
- fprintf (stderr, "Using preinclude %s\n", fname);
-#endif
- return cp + 1;
-
- nope:
-#ifdef DEBUG_PCP
- fprintf (stderr, "Cannot use preinclude %s\n", fname);
-#endif
- free (buf);
- return 0;
-}
-
-/* PREC (null terminated) points to the preconditions of a
- precompiled header. These are a series of #define and #undef
- lines which must match the current contents of the hash
- table. */
-
-static int
-check_preconditions (prec)
- const char *prec;
-{
- MACRODEF mdef;
- const char *lineend;
-
- while (*prec) {
- lineend = index (prec, '\n');
-
- if (*prec++ != '#') {
- error ("Bad format encountered while reading precompiled file");
- return 0;
- }
- if (!strncmp (prec, "define", 6)) {
- HASHNODE *hp;
-
- prec += 6;
- mdef = create_definition ((const U_CHAR *) prec,
- (const U_CHAR *) lineend, NULL_PTR);
-
- if (mdef.defn == 0)
- abort ();
-
- if ((hp = lookup (mdef.symnam, mdef.symlen, -1)) == NULL
- || (hp->type != T_MACRO && hp->type != T_CONST)
- || (hp->type == T_MACRO
- && !compare_defs (mdef.defn, hp->value.defn)
- && (mdef.defn->length != 2
- || mdef.defn->expansion[0] != '\n'
- || mdef.defn->expansion[1] != ' ')))
- return 0;
- } else if (!strncmp (prec, "undef", 5)) {
- const char *name;
- int len;
-
- prec += 5;
- while (is_hor_space[(U_CHAR) *prec])
- prec++;
- name = prec;
- while (is_idchar[(U_CHAR) *prec])
- prec++;
- len = prec - name;
-
- if (lookup ((const U_CHAR *) name, len, -1))
- return 0;
- } else {
- error ("Bad format encountered while reading precompiled file");
- return 0;
- }
- prec = lineend + 1;
- }
- /* They all passed successfully */
- return 1;
-}
-
-/* Process the main body of a precompiled file. BUF points to the
- string section of the file, following the preconditions. LIMIT is one
- character past the end. NAME is the name of the file being read
- in. OP is the main output buffer. */
-
-static void
-pcfinclude (buf, name, op)
- U_CHAR *buf;
- const U_CHAR *name;
- FILE_BUF *op;
-{
- FILE_BUF tmpbuf;
- int nstrings;
- U_CHAR *cp = buf;
-
- /* First in the file comes 4 bytes indicating the number of strings, */
- /* in network byte order. (MSB first). */
- nstrings = *cp++;
- nstrings = (nstrings << 8) | *cp++;
- nstrings = (nstrings << 8) | *cp++;
- nstrings = (nstrings << 8) | *cp++;
-
- /* Looping over each string... */
- while (nstrings--) {
- U_CHAR *string_start;
- U_CHAR *endofthiskey;
- STRINGDEF *str;
- int nkeys;
-
- /* Each string starts with a STRINGDEF structure (str), followed */
- /* by the text of the string (string_start) */
-
- /* First skip to a longword boundary */
- /* ??? Why a 4-byte boundary? On all machines? */
- /* NOTE: This works correctly even if size_t
- is narrower than a pointer.
- Do not try risky measures here to get another type to use!
- Do not include stddef.h--it will fail! */
- if ((size_t) cp & 3)
- cp += 4 - ((size_t) cp & 3);
-
- /* Now get the string. */
- str = (STRINGDEF *) (PTR) cp;
- string_start = cp += sizeof (STRINGDEF);
-
- for (; *cp; cp++) /* skip the string */
- ;
-
- /* We need to macro expand the string here to ensure that the
- proper definition environment is in place. If it were only
- expanded when we find out it is needed, macros necessary for
- its proper expansion might have had their definitions changed. */
- tmpbuf = expand_to_temp_buffer (string_start, cp++, 0, 0);
- /* Lineno is already set in the precompiled file */
- str->contents = tmpbuf.buf;
- str->len = tmpbuf.bufp - tmpbuf.buf;
- str->writeflag = 0;
- str->filename = name;
- str->output_mark = outbuf.bufp - outbuf.buf;
-
- str->chain = 0;
- *stringlist_tailp = str;
- stringlist_tailp = &str->chain;
-
- /* Next comes a fourbyte number indicating the number of keys
- for this string. */
- nkeys = *cp++;
- nkeys = (nkeys << 8) | *cp++;
- nkeys = (nkeys << 8) | *cp++;
- nkeys = (nkeys << 8) | *cp++;
-
- /* If this number is -1, then the string is mandatory. */
- if (nkeys == -1)
- str->writeflag = 1;
- else
- /* Otherwise, for each key, */
- for (; nkeys--; free (tmpbuf.buf), cp = endofthiskey + 1) {
- KEYDEF *kp = (KEYDEF *) (PTR) cp;
- HASHNODE *hp;
- U_CHAR *bp;
-
- /* It starts with a KEYDEF structure */
- cp += sizeof (KEYDEF);
-
- /* Find the end of the key. At the end of this for loop we
- advance CP to the start of the next key using this variable. */
- endofthiskey = cp + strlen ((char *) cp);
- kp->str = str;
-
- /* Expand the key, and enter it into the hash table. */
- tmpbuf = expand_to_temp_buffer (cp, endofthiskey, 0, 0);
- bp = tmpbuf.buf;
-
- while (is_hor_space[*bp])
- bp++;
- if (!is_idstart[*bp] || bp == tmpbuf.bufp) {
- str->writeflag = 1;
- continue;
- }
-
- hp = lookup (bp, -1, -1);
- if (hp == NULL) {
- kp->chain = 0;
- install (bp, -1, T_PCSTRING, (char *) kp, -1);
- }
- else if (hp->type == T_PCSTRING) {
- kp->chain = hp->value.keydef;
- hp->value.keydef = kp;
- }
- else
- str->writeflag = 1;
- }
- }
- /* This output_line_directive serves to switch us back to the current
- input file in case some of these strings get output (which will
- result in line directives for the header file being output). */
- output_line_directive (&instack[indepth], op, 0, enter_file);
-}
-
-/* Called from rescan when it hits a key for strings. Mark them all
- used and clean up. */
-
-static void
-pcstring_used (hp)
- HASHNODE *hp;
-{
- KEYDEF *kp;
-
- for (kp = hp->value.keydef; kp; kp = kp->chain)
- kp->str->writeflag = 1;
- delete_macro (hp);
-}
-
-/* Write the output, interspersing precompiled strings in their
- appropriate places. */
-
-static void
-write_output ()
-{
- STRINGDEF *next_string;
- U_CHAR *cur_buf_loc;
- int line_directive_len = 80;
- char *line_directive = xmalloc (line_directive_len);
- int len;
-
- /* In each run through the loop, either cur_buf_loc ==
- next_string_loc, in which case we print a series of strings, or
- it is less than next_string_loc, in which case we write some of
- the buffer. */
- cur_buf_loc = outbuf.buf;
- next_string = stringlist;
-
- while (cur_buf_loc < outbuf.bufp || next_string) {
- if (next_string
- && cur_buf_loc - outbuf.buf == next_string->output_mark) {
- if (next_string->writeflag) {
- len = 4 * strlen ((const char *) next_string->filename) + 32;
- while (len > line_directive_len)
- line_directive = xrealloc (line_directive,
- line_directive_len *= 2);
- sprintf (line_directive, "\n# %d ", next_string->lineno);
- strcpy (quote_string (line_directive + strlen (line_directive),
- (const char *) next_string->filename,
- strlen ((const char *) next_string->filename)),
- "\n");
- safe_write (fileno (stdout), line_directive, strlen (line_directive));
- safe_write (fileno (stdout),
- (char *) next_string->contents, next_string->len);
- }
- next_string = next_string->chain;
- }
- else {
- len = (next_string
- ? (next_string->output_mark
- - (cur_buf_loc - outbuf.buf))
- : outbuf.bufp - cur_buf_loc);
-
- safe_write (fileno (stdout), (char *) cur_buf_loc, len);
- cur_buf_loc += len;
- }
- }
- free (line_directive);
-}
-
-/* Pass a directive through to the output file.
- BUF points to the contents of the directive, as a contiguous string.
- LIMIT points to the first character past the end of the directive.
- KEYWORD is the keyword-table entry for the directive. */
-
-static void
-pass_thru_directive (buf, limit, op, keyword)
- const U_CHAR *buf;
- const U_CHAR *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- register int keyword_length = keyword->length;
-
- check_expand (op, 1 + keyword_length + (limit - buf));
- *op->bufp++ = '#';
- bcopy (keyword->name, (char *) op->bufp, keyword_length);
- op->bufp += keyword_length;
- if (limit != buf && buf[0] != ' ')
- *op->bufp++ = ' ';
- bcopy ((const PTR) buf, (PTR) op->bufp, limit - buf);
- op->bufp += (limit - buf);
-#if 0
- *op->bufp++ = '\n';
- /* Count the line we have just made in the output,
- to get in sync properly. */
- op->lineno++;
-#endif
-}
-
-/* The arglist structure is built by do_define to tell
- collect_definition where the argument names begin. That
- is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
- would contain pointers to the strings x, y, and z.
- Collect_definition would then build a DEFINITION node,
- with reflist nodes pointing to the places x, y, and z had
- appeared. So the arglist is just convenience data passed
- between these two routines. It is not kept around after
- the current #define has been processed and entered into the
- hash table. */
-
-struct arglist {
- struct arglist *next;
- const U_CHAR *name;
- int length;
- int argno;
- char rest_args;
-};
-
-/* Create a DEFINITION node from a #define directive. Arguments are
- as for do_define. */
-
-static MACRODEF
-create_definition (buf, limit, op)
- const U_CHAR *buf, *limit;
- FILE_BUF *op;
-{
- const U_CHAR *bp; /* temp ptr into input buffer */
- const U_CHAR *symname; /* remember where symbol name starts */
- int sym_length; /* and how long it is */
- int line = instack[indepth].lineno;
- const char *file = instack[indepth].nominal_fname;
- size_t file_len = instack[indepth].nominal_fname_len;
- int rest_args = 0;
-
- DEFINITION *defn;
- int arglengths = 0; /* Accumulate lengths of arg names
- plus number of args. */
- MACRODEF mdef;
-
- bp = buf;
-
- while (is_hor_space[*bp])
- bp++;
-
- symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, 0);
- bp += sym_length;
-
- /* Lossage will occur if identifiers or control keywords are broken
- across lines using backslash. This is not the right place to take
- care of that. */
-
- if (*bp == '(') {
- struct arglist *arg_ptrs = NULL;
- int argno = 0;
-
- bp++; /* skip '(' */
- SKIP_WHITE_SPACE (bp);
-
- /* Loop over macro argument names. */
- while (*bp != ')') {
- struct arglist *temp;
-
- temp = (struct arglist *) alloca (sizeof (struct arglist));
- temp->name = bp;
- temp->next = arg_ptrs;
- temp->argno = argno++;
- temp->rest_args = 0;
- arg_ptrs = temp;
-
- if (rest_args)
- pedwarn ("another parameter follows `%s'",
- rest_extension);
-
- if (!is_idstart[*bp])
- {
- if (c99 && limit - bp > (long) REST_EXTENSION_LENGTH
- && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
- {
- /* This is the ISO C 99 way to write macros with variable
- number of arguments. */
- rest_args = 1;
- temp->rest_args = 1;
- }
- else
- pedwarn ("invalid character in macro parameter name");
- }
-
- /* Find the end of the arg name. */
- while (is_idchar[*bp]) {
- bp++;
- /* do we have a "special" rest-args extension here? */
- if (limit - bp > (long) REST_EXTENSION_LENGTH
- && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
- if (pedantic && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow macro with variable arguments");
- rest_args = 1;
- temp->rest_args = 1;
- break;
- }
- }
- if (bp == temp->name && rest_args == 1)
- {
- /* This is the ISO C 99 style. */
- temp->name = (U_CHAR *) va_args_name;
- temp->length = VA_ARGS_NAME_LENGTH;
- }
- else
- temp->length = bp - temp->name;
- if (rest_args == 1)
- bp += REST_EXTENSION_LENGTH;
- arglengths += temp->length + 2;
- SKIP_WHITE_SPACE (bp);
- if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
- error ("badly punctuated parameter list in `#define'");
- goto nope;
- }
- if (*bp == ',') {
- bp++;
- SKIP_WHITE_SPACE (bp);
- /* A comma at this point can only be followed by an identifier. */
- if (!is_idstart[*bp]
- && !(c99 && limit - bp > (long) REST_EXTENSION_LENGTH
- && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)) {
- error ("badly punctuated parameter list in `#define'");
- goto nope;
- }
- }
- if (bp >= limit) {
- error ("unterminated parameter list in `#define'");
- goto nope;
- }
- {
- struct arglist *otemp;
-
- for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
- if (temp->length == otemp->length
- && bcmp (temp->name, otemp->name, temp->length) == 0)
- {
- error ("duplicate argument name `%.*s' in `#define'",
- temp->length, temp->name);
- goto nope;
- }
- if (rest_args == 0 && temp->length == VA_ARGS_NAME_LENGTH
- && bcmp (temp->name, va_args_name, VA_ARGS_NAME_LENGTH) == 0)
- {
- error ("\
-reserved name `%s' used as argument name in `#define'", va_args_name);
- goto nope;
- }
- }
- }
-
- ++bp; /* skip paren */
- SKIP_WHITE_SPACE (bp);
- /* now everything from bp before limit is the definition. */
- defn = collect_expansion (bp, limit, argno, arg_ptrs);
- defn->rest_args = rest_args;
-
- /* Now set defn->args.argnames to the result of concatenating
- the argument names in reverse order
- with comma-space between them. */
- defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1);
- {
- struct arglist *temp;
- int i = 0;
- for (temp = arg_ptrs; temp; temp = temp->next) {
- bcopy (temp->name, &defn->args.argnames[i], temp->length);
- i += temp->length;
- if (temp->next != 0) {
- defn->args.argnames[i++] = ',';
- defn->args.argnames[i++] = ' ';
- }
- }
- defn->args.argnames[i] = 0;
- }
- } else {
- /* Simple expansion or empty definition. */
-
- if (bp < limit)
- {
- if (is_hor_space[*bp]) {
- bp++;
- SKIP_WHITE_SPACE (bp);
- } else if (sym_length) {
- switch (*bp) {
- case '!': case '"': case '#': case '%': case '&': case '\'':
- case ')': case '*': case '+': case ',': case '-': case '.':
- case '/': case ':': case ';': case '<': case '=': case '>':
- case '?': case '[': case '\\': case ']': case '^': case '{':
- case '|': case '}': case '~':
- warning ("missing white space after `#define %.*s'",
- sym_length, symname);
- break;
-
- default:
- pedwarn ("missing white space after `#define %.*s'",
- sym_length, symname);
- break;
- }
- }
- }
- /* Now everything from bp before limit is the definition. */
- defn = collect_expansion (bp, limit, -1, NULL_PTR);
- defn->args.argnames = (U_CHAR *) "";
- }
-
- defn->line = line;
- defn->file = file;
- defn->file_len = file_len;
-
- /* OP is null if this is a predefinition */
- defn->predefined = !op;
- mdef.defn = defn;
- mdef.symnam = symname;
- mdef.symlen = sym_length;
-
- return mdef;
-
- nope:
- mdef.defn = 0;
- return mdef;
-}
-
-/* Process a #define directive.
-BUF points to the contents of the #define directive, as a contiguous string.
-LIMIT points to the first character past the end of the definition.
-KEYWORD is the keyword-table entry for #define. */
-
-static int
-do_define (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- int hashcode;
- MACRODEF mdef;
- enum node_type newtype = keyword->type == T_DEFINE ? T_MACRO : T_POISON;
-
- /* If this is a precompiler run (with -pcp) pass thru #define directives. */
- if (pcp_outfile && op)
- pass_thru_directive (buf, limit, op, keyword);
-
- mdef = create_definition (buf, limit, op);
- if (mdef.defn == 0)
- goto nope;
-
- hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE);
-
- {
- HASHNODE *hp;
- if ((hp = lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL) {
- int ok = 0;
- /* Redefining a precompiled key is ok. */
- if (hp->type == T_PCSTRING)
- ok = 1;
- /* Redefining a poisoned identifier is even worse than `not ok'. */
- else if (hp->type == T_POISON)
- ok = -1;
- /* Poisoning anything else is not ok.
- The poison should always come first. */
- else if (newtype == T_POISON)
- ok = 0;
- /* Redefining a macro is ok if the definitions are the same. */
- else if (hp->type == T_MACRO)
- ok = ! compare_defs (mdef.defn, hp->value.defn);
- /* Redefining a constant is ok with -D. */
- else if (hp->type == T_CONST)
- ok = ! done_initializing;
-
- /* Print the warning or error if it's not ok. */
- if (ok <= 0)
- {
- /* If we are passing through #define and #undef directives, do
- that for this re-definition now. */
- if (debug_output && op)
- pass_thru_directive (buf, limit, op, keyword);
-
- if (hp->type == T_POISON)
- error ("redefining poisoned `%.*s'", mdef.symlen, mdef.symnam);
- else
- pedwarn ("`%.*s' redefined", mdef.symlen, mdef.symnam);
- if (hp->type == T_MACRO)
- pedwarn_with_file_and_line (hp->value.defn->file,
- hp->value.defn->file_len,
- hp->value.defn->line,
- "this is the location of the previous definition");
- }
- if (hp->type != T_POISON)
- {
- /* Replace the old definition. */
- hp->type = newtype;
- hp->value.defn = mdef.defn;
- }
- } else {
- /* If we are passing through #define and #undef directives, do
- that for this new definition now. */
- if (debug_output && op)
- pass_thru_directive (buf, limit, op, keyword);
- install (mdef.symnam, mdef.symlen, newtype,
- (char *) mdef.defn, hashcode);
- }
- }
-
- return 0;
-
-nope:
-
- return 1;
-}
-
-/* Check a purported macro name SYMNAME, and yield its length.
- ASSERTION is nonzero if this is really for an assertion name. */
-
-static int
-check_macro_name (symname, assertion)
- const U_CHAR *symname;
- int assertion;
-{
- const U_CHAR *p;
- int sym_length;
-
- for (p = symname; is_idchar[*p]; p++)
- ;
- sym_length = p - symname;
- if (sym_length == 0
- || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"')))
- {
- if (assertion)
- error ("invalid assertion name");
- else
- error ("invalid macro name");
- }
- else if (!is_idstart[*symname]
- || (sym_length == 7 && ! bcmp (symname, "defined", 7)))
- {
- if (assertion)
- error ("invalid assertion name `%.*s'", sym_length, symname);
- else
- error ("invalid macro name `%.*s'", sym_length, symname);
- }
- return sym_length;
-}
-
-/* Return zero if two DEFINITIONs are isomorphic. */
-
-static int
-compare_defs (d1, d2)
- DEFINITION *d1, *d2;
-{
- register struct reflist *a1, *a2;
- register U_CHAR *p1 = d1->expansion;
- register U_CHAR *p2 = d2->expansion;
- int first = 1;
-
- if (d1->nargs != d2->nargs)
- return 1;
- if (pedantic
- && strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames))
- return 1;
- for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
- a1 = a1->next, a2 = a2->next) {
- if (!((a1->nchars == a2->nchars && ! bcmp (p1, p2, a1->nchars))
- || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
- || a1->argno != a2->argno
- || a1->stringify != a2->stringify
- || a1->raw_before != a2->raw_before
- || a1->raw_after != a2->raw_after)
- return 1;
- first = 0;
- p1 += a1->nchars;
- p2 += a2->nchars;
- }
- if (a1 != a2)
- return 1;
- if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
- p2, d2->length - (p2 - d2->expansion), 1))
- return 1;
- return 0;
-}
-
-/* Return 1 if two parts of two macro definitions are effectively different.
- One of the parts starts at BEG1 and has LEN1 chars;
- the other has LEN2 chars at BEG2.
- Any sequence of whitespace matches any other sequence of whitespace.
- FIRST means these parts are the first of a macro definition;
- so ignore leading whitespace entirely.
- LAST means these parts are the last of a macro definition;
- so ignore trailing whitespace entirely. */
-
-static int
-comp_def_part (first, beg1, len1, beg2, len2, last)
- int first;
- const U_CHAR *beg1, *beg2;
- int len1, len2;
- int last;
-{
- register const U_CHAR *end1 = beg1 + len1;
- register const U_CHAR *end2 = beg2 + len2;
- if (first) {
- while (beg1 != end1 && is_space[*beg1]) beg1++;
- while (beg2 != end2 && is_space[*beg2]) beg2++;
- }
- if (last) {
- while (beg1 != end1 && is_space[end1[-1]]) end1--;
- while (beg2 != end2 && is_space[end2[-1]]) end2--;
- }
- while (beg1 != end1 && beg2 != end2) {
- if (is_space[*beg1] && is_space[*beg2]) {
- while (beg1 != end1 && is_space[*beg1]) beg1++;
- while (beg2 != end2 && is_space[*beg2]) beg2++;
- } else if (*beg1 == *beg2) {
- beg1++; beg2++;
- } else break;
- }
- return (beg1 != end1) || (beg2 != end2);
-}
-
-/* Read a replacement list for a macro with parameters.
- Build the DEFINITION structure.
- Reads characters of text starting at BUF until END.
- ARGLIST specifies the formal parameters to look for
- in the text of the definition; NARGS is the number of args
- in that list, or -1 for a macro name that wants no argument list.
- MACRONAME is the macro name itself (so we can avoid recursive expansion)
- and NAMELEN is its length in characters.
-
-Note that comments, backslash-newlines, and leading white space
-have already been deleted from the argument. */
-
-/* If there is no trailing whitespace, a Newline Space is added at the end
- to prevent concatenation that would be contrary to the standard. */
-
-static DEFINITION *
-collect_expansion (buf, end, nargs, arglist)
- const U_CHAR *buf;
- const U_CHAR *end;
- int nargs;
- struct arglist *arglist;
-{
- DEFINITION *defn;
- register const U_CHAR *p;
- register const U_CHAR *limit;
- register U_CHAR *lastp, *exp_p;
- struct reflist *endpat = NULL;
- /* Pointer to first nonspace after last ## seen. */
- const U_CHAR *concat = 0;
- /* Pointer to first nonspace after last single-# seen. */
- const U_CHAR *stringify = 0;
- /* How those tokens were spelled. */
- enum sharp_token_type concat_sharp_token_type = NO_SHARP_TOKEN;
- enum sharp_token_type stringify_sharp_token_type = NO_SHARP_TOKEN;
- int maxsize;
- int expected_delimiter = '\0';
-
- /* Scan thru the replacement list, ignoring comments and quoted
- strings, picking up on the macro calls. It does a linear search
- thru the arg list on every potential symbol. Profiling might say
- that something smarter should happen. */
-
- if (end < buf)
- abort ();
-
- /* Find the beginning of the trailing whitespace. */
- limit = end;
- p = buf;
- while (p < limit && is_space[limit[-1]]) limit--;
-
- /* Allocate space for the text in the macro definition.
- Each input char may or may not need 1 byte,
- so this is an upper bound.
- The extra 3 are for invented trailing newline-marker and final null. */
- maxsize = (sizeof (DEFINITION)
- + (limit - p) + 3);
- defn = (DEFINITION *) xcalloc (1, maxsize);
-
- defn->nargs = nargs;
- exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION);
- lastp = exp_p;
-
- if (p[0] == '#'
- ? p[1] == '#'
- : p[0] == '%' && p[1] == ':' && p[2] == '%' && p[3] == ':') {
- error ("`##' at start of macro definition");
- p += p[0] == '#' ? 2 : 4;
- }
-
- /* Process the main body of the definition. */
- while (p < limit) {
- int skipped_arg = 0;
- register U_CHAR c = *p++;
-
- *exp_p++ = c;
-
- if (!traditional) {
- switch (c) {
- case '\'':
- case '\"':
- if (expected_delimiter != '\0') {
- if (c == expected_delimiter)
- expected_delimiter = '\0';
- } else
- expected_delimiter = c;
- break;
-
- case '\\':
- if (expected_delimiter) {
- /* In a string, backslash goes through
- and makes next char ordinary. */
- *exp_p++ = *p++;
- }
- break;
-
- case '%':
- if (!expected_delimiter && *p == ':') {
- /* %: is not a digraph if preceded by an odd number of '<'s. */
- const U_CHAR *p0 = p - 1;
- while (buf < p0 && p0[-1] == '<')
- p0--;
- if ((p - p0) & 1) {
- /* Treat %:%: as ## and %: as #. */
- if (p[1] == '%' && p[2] == ':') {
- p += 2;
- goto sharp_sharp_token;
- }
- if (nargs >= 0) {
- p++;
- goto sharp_token;
- }
- }
- }
- break;
-
- case '#':
- /* # is ordinary inside a string. */
- if (expected_delimiter)
- break;
- if (*p == '#') {
- sharp_sharp_token:
- /* ##: concatenate preceding and following tokens. */
- /* Take out the first #, discard preceding whitespace. */
- exp_p--;
- while (exp_p > lastp && is_hor_space[exp_p[-1]])
- --exp_p;
- /* Skip the second #. */
- p++;
- concat_sharp_token_type = c;
- if (is_hor_space[*p]) {
- concat_sharp_token_type = c + 1;
- p++;
- SKIP_WHITE_SPACE (p);
- }
- concat = p;
- if (p == limit)
- error ("`##' at end of macro definition");
- } else if (nargs >= 0) {
- /* Single #: stringify following argument ref.
- Don't leave the # in the expansion. */
- sharp_token:
- exp_p--;
- stringify_sharp_token_type = c;
- if (is_hor_space[*p]) {
- stringify_sharp_token_type = c + 1;
- p++;
- SKIP_WHITE_SPACE (p);
- }
- if (! is_idstart[*p] || nargs == 0
- || (*p == 'L' && (p[1] == '\'' || p[1] == '"')))
- error ("`#' operator is not followed by a macro argument name");
- else
- stringify = p;
- }
- break;
- }
- } else {
- /* In -traditional mode, recognize arguments inside strings and
- character constants, and ignore special properties of #.
- Arguments inside strings are considered "stringified", but no
- extra quote marks are supplied. */
- switch (c) {
- case '\'':
- case '\"':
- if (expected_delimiter != '\0') {
- if (c == expected_delimiter)
- expected_delimiter = '\0';
- } else
- expected_delimiter = c;
- break;
-
- case '\\':
- /* Backslash quotes delimiters and itself, but not macro args. */
- if (expected_delimiter != 0 && p < limit
- && (*p == expected_delimiter || *p == '\\')) {
- *exp_p++ = *p++;
- continue;
- }
- break;
-
- case '/':
- if (expected_delimiter != '\0') /* No comments inside strings. */
- break;
- if (*p == '*') {
- /* If we find a comment that wasn't removed by handle_directive,
- this must be -traditional. So replace the comment with
- nothing at all. */
- exp_p--;
- while (++p < limit) {
- if (p[0] == '*' && p[1] == '/') {
- p += 2;
- break;
- }
- }
-#if 0
- /* Mark this as a concatenation-point, as if it had been ##. */
- concat = p;
-#endif
- }
- break;
- }
- }
-
-#ifdef MULTIBYTE_CHARS
- /* Handle multibyte characters inside string and character literals. */
- if (expected_delimiter != '\0')
- {
- int length;
- --p;
- length = local_mblen (p, limit - p);
- if (length > 1)
- {
- --exp_p;
- bcopy (p, exp_p, length);
- p += length;
- exp_p += length;
- continue;
- }
- ++p;
- }
-#endif
-
- /* Handle the start of a symbol. */
- if (is_idchar[c] && nargs > 0) {
- const U_CHAR *id_beg = p - 1;
- int id_len;
-
- --exp_p;
- while (p != limit && is_idchar[*p]) p++;
- id_len = p - id_beg;
-
- if (is_idstart[c]
- && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) {
- register struct arglist *arg;
-
- for (arg = arglist; arg != NULL; arg = arg->next) {
- struct reflist *tpat;
-
- if (arg->name[0] == c
- && arg->length == id_len
- && bcmp (arg->name, id_beg, id_len) == 0) {
- enum sharp_token_type tpat_stringify;
- if (expected_delimiter) {
- if (warn_stringify) {
- if (traditional) {
- warning ("macro argument `%.*s' is stringified.",
- id_len, arg->name);
- } else {
- warning ("macro arg `%.*s' would be stringified with -traditional.",
- id_len, arg->name);
- }
- }
- /* If ANSI, don't actually substitute inside a string. */
- if (!traditional)
- break;
- tpat_stringify = SHARP_TOKEN;
- } else {
- tpat_stringify
- = (stringify == id_beg
- ? stringify_sharp_token_type : NO_SHARP_TOKEN);
- }
- /* make a pat node for this arg and append it to the end of
- the pat list */
- tpat = (struct reflist *) xmalloc (sizeof (struct reflist));
- tpat->next = NULL;
- tpat->raw_before
- = concat == id_beg ? concat_sharp_token_type : NO_SHARP_TOKEN;
- tpat->raw_after = NO_SHARP_TOKEN;
- tpat->rest_args = arg->rest_args;
- tpat->stringify = tpat_stringify;
-
- if (endpat == NULL)
- defn->pattern = tpat;
- else
- endpat->next = tpat;
- endpat = tpat;
-
- tpat->argno = arg->argno;
- tpat->nchars = exp_p - lastp;
- {
- register const U_CHAR *p1 = p;
- SKIP_WHITE_SPACE (p1);
- if (p1[0]=='#'
- ? p1[1]=='#'
- : p1[0]=='%' && p1[1]==':' && p1[2]=='%' && p1[3]==':')
- tpat->raw_after = p1[0] + (p != p1);
- }
- lastp = exp_p; /* place to start copying from next time */
- skipped_arg = 1;
- break;
- }
- }
- }
-
- /* If this was not a macro arg, copy it into the expansion. */
- if (! skipped_arg) {
- register const U_CHAR *lim1 = p;
- p = id_beg;
- while (p != lim1)
- *exp_p++ = *p++;
- if (stringify == id_beg)
- error ("`#' operator should be followed by a macro argument name");
- }
- }
- }
-
- if (!traditional && expected_delimiter == 0) {
- /* If ANSI, put in a newline-space marker to prevent token pasting.
- But not if "inside a string" (which in ANSI mode happens only for
- -D option). */
- *exp_p++ = '\n';
- *exp_p++ = ' ';
- }
-
- *exp_p = '\0';
-
- defn->length = exp_p - defn->expansion;
-
- /* Crash now if we overrun the allocated size. */
- if (defn->length + 1 > maxsize)
- abort ();
-
-#if 0
-/* This isn't worth the time it takes. */
- /* give back excess storage */
- defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1);
-#endif
-
- return defn;
-}
-
-static int
-do_assert (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- const U_CHAR *bp; /* temp ptr into input buffer */
- const U_CHAR *symname; /* remember where symbol name starts */
- int sym_length; /* and how long it is */
- struct arglist *tokens = NULL;
-
- if (pedantic && done_initializing && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow `#assert'");
-
- bp = buf;
-
- while (is_hor_space[*bp])
- bp++;
-
- symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, 1);
- bp += sym_length;
- /* #define doesn't do this, but we should. */
- SKIP_WHITE_SPACE (bp);
-
- /* Lossage will occur if identifiers or control tokens are broken
- across lines using backslash. This is not the right place to take
- care of that. */
-
- if (*bp != '(') {
- error ("missing token-sequence in `#assert'");
- return 1;
- }
-
- {
- int error_flag = 0;
-
- bp++; /* skip '(' */
- SKIP_WHITE_SPACE (bp);
-
- tokens = read_token_list (&bp, limit, &error_flag);
- if (error_flag)
- return 1;
- if (tokens == 0) {
- error ("empty token-sequence in `#assert'");
- return 1;
- }
-
- ++bp; /* skip paren */
- SKIP_WHITE_SPACE (bp);
- }
-
- /* If this name isn't already an assertion name, make it one.
- Error if it was already in use in some other way. */
-
- {
- ASSERTION_HASHNODE *hp;
- int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
- struct tokenlist_list *value
- = (struct tokenlist_list *) xmalloc (sizeof (struct tokenlist_list));
-
- hp = assertion_lookup (symname, sym_length, hashcode);
- if (hp == NULL) {
- if (sym_length == 7 && ! bcmp (symname, "defined", 7))
- error ("`defined' redefined as assertion");
- hp = assertion_install (symname, sym_length, hashcode);
- }
-
- /* Add the spec'd token-sequence to the list of such. */
- value->tokens = tokens;
- value->next = hp->value;
- hp->value = value;
- }
-
- return 0;
-}
-
-static int
-do_unassert (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- const U_CHAR *bp; /* temp ptr into input buffer */
- const U_CHAR *symname; /* remember where symbol name starts */
- int sym_length; /* and how long it is */
-
- struct arglist *tokens = NULL;
- int tokens_specified = 0;
-
- if (pedantic && done_initializing && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow `#unassert'");
-
- bp = buf;
-
- while (is_hor_space[*bp])
- bp++;
-
- symname = bp; /* remember where it starts */
- sym_length = check_macro_name (bp, 1);
- bp += sym_length;
- /* #define doesn't do this, but we should. */
- SKIP_WHITE_SPACE (bp);
-
- /* Lossage will occur if identifiers or control tokens are broken
- across lines using backslash. This is not the right place to take
- care of that. */
-
- if (*bp == '(') {
- int error_flag = 0;
-
- bp++; /* skip '(' */
- SKIP_WHITE_SPACE (bp);
-
- tokens = read_token_list (&bp, limit, &error_flag);
- if (error_flag)
- return 1;
- if (tokens == 0) {
- error ("empty token list in `#unassert'");
- return 1;
- }
-
- tokens_specified = 1;
-
- ++bp; /* skip paren */
- SKIP_WHITE_SPACE (bp);
- }
-
- {
- ASSERTION_HASHNODE *hp;
- int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
- struct tokenlist_list *tail, *prev;
-
- hp = assertion_lookup (symname, sym_length, hashcode);
- if (hp == NULL)
- return 1;
-
- /* If no token list was specified, then eliminate this assertion
- entirely. */
- if (! tokens_specified) {
- struct tokenlist_list *next;
- for (tail = hp->value; tail; tail = next) {
- next = tail->next;
- free_token_list (tail->tokens);
- free (tail);
- }
- delete_assertion (hp);
- } else {
- /* If a list of tokens was given, then delete any matching list. */
-
- tail = hp->value;
- prev = 0;
- while (tail) {
- struct tokenlist_list *next = tail->next;
- if (compare_token_lists (tail->tokens, tokens)) {
- if (prev)
- prev->next = next;
- else
- hp->value = tail->next;
- free_token_list (tail->tokens);
- free (tail);
- } else {
- prev = tail;
- }
- tail = next;
- }
- }
- }
-
- return 0;
-}
-
-/* Test whether there is an assertion named NAME
- and optionally whether it has an asserted token list TOKENS.
- NAME is not null terminated; its length is SYM_LENGTH.
- If TOKENS_SPECIFIED is 0, then don't check for any token list. */
-
-int
-check_assertion (name, sym_length, tokens_specified, tokens)
- const U_CHAR *name;
- int sym_length;
- int tokens_specified;
- struct arglist *tokens;
-{
- ASSERTION_HASHNODE *hp;
- int hashcode = hashf (name, sym_length, ASSERTION_HASHSIZE);
-
- if (pedantic && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow testing assertions");
-
- hp = assertion_lookup (name, sym_length, hashcode);
- if (hp == NULL)
- /* It is not an assertion; just return false. */
- return 0;
-
- /* If no token list was specified, then value is 1. */
- if (! tokens_specified)
- return 1;
-
- {
- struct tokenlist_list *tail;
-
- tail = hp->value;
-
- /* If a list of tokens was given,
- then succeed if the assertion records a matching list. */
-
- while (tail) {
- if (compare_token_lists (tail->tokens, tokens))
- return 1;
- tail = tail->next;
- }
-
- /* Fail if the assertion has no matching list. */
- return 0;
- }
-}
-
-/* Compare two lists of tokens for equality including order of tokens. */
-
-static int
-compare_token_lists (l1, l2)
- struct arglist *l1, *l2;
-{
- while (l1 && l2) {
- if (l1->length != l2->length)
- return 0;
- if (bcmp (l1->name, l2->name, l1->length))
- return 0;
- l1 = l1->next;
- l2 = l2->next;
- }
-
- /* Succeed if both lists end at the same time. */
- return l1 == l2;
-}
-
-/* Read a space-separated list of tokens ending in a close parenthesis.
- Return a list of strings, in the order they were written.
- (In case of error, return 0 and store -1 in *ERROR_FLAG.)
- Parse the text starting at *BPP, and update *BPP.
- Don't parse beyond LIMIT. */
-
-static struct arglist *
-read_token_list (bpp, limit, error_flag)
- const U_CHAR **bpp;
- const U_CHAR *limit;
- int *error_flag;
-{
- struct arglist *token_ptrs = 0;
- const U_CHAR *bp = *bpp;
- int depth = 1;
-
- *error_flag = 0;
-
- /* Loop over the assertion value tokens. */
- while (depth > 0) {
- struct arglist *temp;
- U_CHAR *temp2;
- int eofp = 0;
- const U_CHAR *beg = bp;
-
- /* Find the end of the token. */
- if (*bp == '(') {
- bp++;
- depth++;
- } else if (*bp == ')') {
- depth--;
- if (depth == 0)
- break;
- bp++;
- } else if (*bp == '"' || *bp == '\'')
- bp = skip_quoted_string (bp, limit, 0, NULL_PTR, NULL_PTR, &eofp);
- else
- while (! is_hor_space[*bp] && *bp != '(' && *bp != ')'
- && *bp != '"' && *bp != '\'' && bp != limit)
- bp++;
-
- temp = (struct arglist *) xmalloc (sizeof (struct arglist));
- temp2 = (U_CHAR *) xmalloc (bp - beg + 1);
- bcopy ((const PTR) beg, (PTR) temp2, bp - beg);
- temp2[bp - beg] = 0;
- temp->name = temp2;
- temp->next = token_ptrs;
- token_ptrs = temp;
- temp->length = bp - beg;
-
- SKIP_WHITE_SPACE (bp);
-
- if (bp >= limit) {
- error ("unterminated token sequence in `#assert' or `#unassert'");
- *error_flag = -1;
- return 0;
- }
- }
- *bpp = bp;
-
- /* We accumulated the names in reverse order.
- Now reverse them to get the proper order. */
- {
- register struct arglist *prev = 0, *this, *next;
- for (this = token_ptrs; this; this = next) {
- next = this->next;
- this->next = prev;
- prev = this;
- }
- return prev;
- }
-}
-
-static void
-free_token_list (tokens)
- struct arglist *tokens;
-{
- while (tokens) {
- struct arglist *next = tokens->next;
- free ((PTR) tokens->name);
- free (tokens);
- tokens = next;
- }
-}
-
-/* Install a name in the assertion hash table.
-
- If LEN is >= 0, it is the length of the name.
- Otherwise, compute the length by scanning the entire name.
-
- If HASH is >= 0, it is the precomputed hash code.
- Otherwise, compute the hash code. */
-
-static ASSERTION_HASHNODE *
-assertion_install (name, len, hash)
- const U_CHAR *name;
- int len;
- int hash;
-{
- register ASSERTION_HASHNODE *hp;
- register int i, bucket;
- register U_CHAR *p;
- register const U_CHAR *q;
-
- i = sizeof (ASSERTION_HASHNODE) + len + 1;
- hp = (ASSERTION_HASHNODE *) xmalloc (i);
- bucket = hash;
- hp->bucket_hdr = &assertion_hashtab[bucket];
- hp->next = assertion_hashtab[bucket];
- assertion_hashtab[bucket] = hp;
- hp->prev = NULL;
- if (hp->next != NULL)
- hp->next->prev = hp;
- hp->length = len;
- hp->value = 0;
- hp->name = ((U_CHAR *) hp) + sizeof (ASSERTION_HASHNODE);
- p = hp->name;
- q = name;
- for (i = 0; i < len; i++)
- *p++ = *q++;
- hp->name[len] = 0;
- return hp;
-}
-
-/* Find the most recent hash node for name "name" (ending with first
- non-identifier char) installed by install
-
- If LEN is >= 0, it is the length of the name.
- Otherwise, compute the length by scanning the entire name.
-
- If HASH is >= 0, it is the precomputed hash code.
- Otherwise, compute the hash code. */
-
-static ASSERTION_HASHNODE *
-assertion_lookup (name, len, hash)
- const U_CHAR *name;
- int len;
- int hash;
-{
- register ASSERTION_HASHNODE *bucket;
-
- bucket = assertion_hashtab[hash];
- while (bucket) {
- if (bucket->length == len && bcmp (bucket->name, name, len) == 0)
- return bucket;
- bucket = bucket->next;
- }
- return NULL;
-}
-
-static void
-delete_assertion (hp)
- ASSERTION_HASHNODE *hp;
-{
-
- if (hp->prev != NULL)
- hp->prev->next = hp->next;
- if (hp->next != NULL)
- hp->next->prev = hp->prev;
-
- /* Make sure that the bucket chain header that the deleted guy was
- on points to the right thing afterwards. */
- if (hp == *hp->bucket_hdr)
- *hp->bucket_hdr = hp->next;
-
- free (hp);
-}
-
-/*
- * interpret #line directive. Remembers previously seen fnames
- * in its very own hash table.
- */
-#define FNAME_HASHSIZE 37
-
-static int
-do_line (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- register U_CHAR *bp;
- FILE_BUF *ip = &instack[indepth];
- FILE_BUF tem;
- int new_lineno;
- enum file_change_code file_change = same_file;
-
- /* Expand any macros. */
- tem = expand_to_temp_buffer (buf, limit, 0, 0);
-
- /* Point to macroexpanded line, which is null-terminated now. */
- bp = tem.buf;
- limit = tem.bufp;
- SKIP_WHITE_SPACE (bp);
-
- if (!ISDIGIT (*bp)) {
- error ("invalid format `#line' directive");
- return 0;
- }
-
- /* The Newline at the end of this line remains to be processed.
- To put the next line at the specified line number,
- we must store a line number now that is one less. */
- new_lineno = atoi ((char *) bp) - 1;
-
- /* NEW_LINENO is one less than the actual line number here. */
- if (pedantic && new_lineno < 0)
- pedwarn ("line number out of range in `#line' directive");
-
- /* skip over the line number. */
- while (ISDIGIT (*bp))
- bp++;
-
-#if 0 /* #line 10"foo.c" is supposed to be allowed. */
- if (*bp && !is_space[*bp]) {
- error ("invalid format `#line' directive");
- return;
- }
-#endif
-
- SKIP_WHITE_SPACE (bp);
-
- if (*bp == '\"') {
- static HASHNODE *fname_table[FNAME_HASHSIZE];
- HASHNODE *hp, **hash_bucket;
- U_CHAR *fname, *p;
- int fname_length;
-
- fname = ++bp;
-
- /* Turn the file name, which is a character string literal,
- into a null-terminated string. Do this in place. */
- p = bp;
- for (;;)
- switch ((*p++ = *bp++)) {
- case '\\':
- if (! ignore_escape_flag)
- {
- char *bpc = (char *) bp;
- HOST_WIDEST_INT c = parse_escape (&bpc, (HOST_WIDEST_INT) (U_CHAR) (-1));
- bp = (U_CHAR *) bpc;
- if (c < 0)
- p--;
- else
- p[-1] = c;
- }
- break;
-
- case '\"':
- *--p = 0;
- goto fname_done;
- }
- fname_done:
- fname_length = p - fname;
-
- SKIP_WHITE_SPACE (bp);
- if (*bp) {
- if (pedantic)
- pedwarn ("garbage at end of `#line' directive");
- if (*bp == '1')
- file_change = enter_file;
- else if (*bp == '2')
- file_change = leave_file;
- else if (*bp == '3')
- ip->system_header_p = 1;
- else if (*bp == '4')
- ip->system_header_p = 2;
- else {
- error ("invalid format `#line' directive");
- return 0;
- }
-
- bp++;
- SKIP_WHITE_SPACE (bp);
- if (*bp == '3') {
- ip->system_header_p = 1;
- bp++;
- SKIP_WHITE_SPACE (bp);
- }
- if (*bp == '4') {
- ip->system_header_p = 2;
- bp++;
- SKIP_WHITE_SPACE (bp);
- }
- if (*bp) {
- error ("invalid format `#line' directive");
- return 0;
- }
- }
-
- hash_bucket = &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
- for (hp = *hash_bucket; hp != NULL; hp = hp->next)
- if (hp->length == fname_length &&
- bcmp (hp->value.cpval, fname, fname_length) == 0) {
- ip->nominal_fname = hp->value.cpval;
- ip->nominal_fname_len = fname_length;
- break;
- }
- if (hp == 0) {
- /* Didn't find it; cons up a new one. */
- hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1);
- hp->next = *hash_bucket;
- *hash_bucket = hp;
-
- ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE);
- ip->nominal_fname_len = hp->length = fname_length;
- bcopy (fname, ((char *) hp) + sizeof (HASHNODE), fname_length + 1);
- }
- } else if (*bp) {
- error ("invalid format `#line' directive");
- return 0;
- }
-
- ip->lineno = new_lineno;
- output_line_directive (ip, op, 0, file_change);
- check_expand (op, ip->length - (ip->bufp - ip->buf));
- return 0;
-}
-
-/* Remove the definition of a symbol from the symbol table.
- according to un*x /lib/cpp, it is not an error to undef
- something that has no definitions, so it isn't one here either. */
-
-static int
-do_undef (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- int sym_length;
- HASHNODE *hp;
- U_CHAR *orig_buf = buf;
-
- /* If this is a precompiler run (with -pcp) pass thru #undef directives. */
- if (pcp_outfile && op)
- pass_thru_directive (buf, limit, op, keyword);
-
- SKIP_WHITE_SPACE (buf);
- sym_length = check_macro_name (buf, 0);
-
- while ((hp = lookup (buf, sym_length, -1)) != NULL) {
- /* If we are generating additional info for debugging (with -g) we
- need to pass through all effective #undef directives. */
- if (debug_output && op)
- pass_thru_directive (orig_buf, limit, op, keyword);
- if (hp->type == T_POISON)
- error ("cannot undefine poisoned `%s'", hp->name);
- else {
- if (hp->type != T_MACRO)
- warning ("undefining `%s'", hp->name);
- delete_macro (hp);
- }
- }
-
- if (pedantic) {
- buf += sym_length;
- SKIP_WHITE_SPACE (buf);
- if (buf != limit)
- pedwarn ("garbage after `#undef' directive");
- }
- return 0;
-}
-
-
-/* Report an error detected by the program we are processing.
- Use the text of the line in the error message. */
-
-static int
-do_error (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword;
-{
- int length = limit - buf;
- U_CHAR *copy = (U_CHAR *) alloca (length + 1);
- bcopy ((const PTR) buf, (PTR) copy, length);
- copy[length] = 0;
- SKIP_WHITE_SPACE (copy);
-
- switch (keyword->type) {
- case T_ERROR:
- error ("#error %s", copy);
- break;
-
- case T_WARNING:
- if (pedantic && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow `#warning'");
- warning ("#warning %s", copy);
- break;
-
- default:
- abort ();
- }
-
- return 0;
-}
-/* Remember the name of the current file being read from so that we can
- avoid ever including it again. */
-
-static void
-do_once ()
-{
- int i;
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].inc) {
- record_control_macro (instack[i].inc, (const U_CHAR *) "");
- break;
- }
-}
-
-/* Report program identification. */
-
-static int
-do_ident (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- FILE_BUF trybuf;
- int len;
-
- /* Allow #ident in system headers, since that's not user's fault. */
- if (pedantic && !instack[indepth].system_header_p)
- pedwarn ("ANSI C does not allow `#ident'");
-
- trybuf = expand_to_temp_buffer (buf, limit, 0, 0);
- buf = trybuf.buf;
- len = trybuf.bufp - buf;
-
- /* Output expanded directive. */
- check_expand (op, 7 + len);
- bcopy ("#ident ", (char *) op->bufp, 7);
- op->bufp += 7;
- bcopy ((const PTR) buf, (PTR) op->bufp, len);
- op->bufp += len;
-
- free (buf);
- return 0;
-}
-
-/* #pragma and its argument line have already been copied to the output file.
- Just check for some recognized pragmas that need validation here. */
-
-static int
-do_pragma (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- SKIP_WHITE_SPACE (buf);
- if (!strncmp ((char *) buf, "once", 4)) {
- /* Allow #pragma once in system headers, since that's not the user's
- fault. */
- if (!instack[indepth].system_header_p)
- warning ("`#pragma once' is obsolete");
- do_once ();
- }
-
- if (!strncmp ((char *) buf, "poison", 6)) {
- /* Poison these symbols so that all subsequent usage produces an
- error message. */
- U_CHAR *p = buf + 6;
-
- SKIP_WHITE_SPACE (p);
- while (p < limit)
- {
- U_CHAR *end = p;
-
- while (end < limit && is_idchar[*end])
- end++;
- if (end < limit && !is_space[*end])
- {
- error ("invalid #pragma poison");
- return 0;
- }
- do_define(p, end, op, keyword);
- p = end;
- SKIP_WHITE_SPACE (p);
- }
- }
-
- if (!strncmp ((char *) buf, "implementation", 14)) {
- /* Be quiet about `#pragma implementation' for a file only if it hasn't
- been included yet. */
-
- int h;
- U_CHAR *p = buf + 14, *fname;
- SKIP_WHITE_SPACE (p);
- if (*p != '\"')
- return 0;
-
- fname = p + 1;
- p = skip_quoted_string (p, limit, 0, NULL_PTR, NULL_PTR, NULL_PTR);
- if (p[-1] == '"')
- *--p = '\0';
-
- for (h = 0; h < INCLUDE_HASHSIZE; h++) {
- struct include_file *inc;
- for (inc = include_hashtab[h]; inc; inc = inc->next) {
- if (!strcmp (base_name (inc->fname), (char *) fname)) {
- warning ("`#pragma implementation' for \"%s\" appears after its #include",fname);
- return 0;
- }
- }
- }
- }
- return 0;
-}
-
-#if 0
-/* This was a fun hack, but #pragma seems to start to be useful.
- By failing to recognize it, we pass it through unchanged to cc1. */
-
-/* The behavior of the #pragma directive is implementation defined.
- this implementation defines it as follows. */
-
-static int
-do_pragma ()
-{
- close (0);
- if (open ("/dev/tty", O_RDONLY, 0666) != 0)
- goto nope;
- close (1);
- if (open ("/dev/tty", O_WRONLY, 0666) != 1)
- goto nope;
- execl ("/usr/games/hack", "#pragma", 0);
- execl ("/usr/games/rogue", "#pragma", 0);
- execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
- execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
-nope:
- fatal ("You are in a maze of twisty compiler features, all different");
-}
-#endif
-
-#ifdef SCCS_DIRECTIVE
-
-/* Just ignore #sccs, on systems where we define it at all. */
-
-static int
-do_sccs (buf, limit, op, keyword)
- U_CHAR *buf ATTRIBUTE_UNUSED;
- U_CHAR *limit ATTRIBUTE_UNUSED;
- FILE_BUF *op ATTRIBUTE_UNUSED;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- if (pedantic)
- pedwarn ("ANSI C does not allow `#sccs'");
- return 0;
-}
-
-#endif /* defined (SCCS_DIRECTIVE) */
-
-/* Handle #if directive by
- 1) inserting special `defined' keyword into the hash table
- that gets turned into 0 or 1 by special_symbol (thus,
- if the luser has a symbol called `defined' already, it won't
- work inside the #if directive)
- 2) rescan the input into a temporary output buffer
- 3) pass the output buffer to the yacc parser and collect a value
- 4) clean up the mess left from steps 1 and 2.
- 5) call conditional_skip to skip til the next #endif (etc.),
- or not, depending on the value from step 3. */
-
-static int
-do_if (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- HOST_WIDEST_INT value;
- FILE_BUF *ip = &instack[indepth];
-
- value = eval_if_expression (buf, limit - buf);
- conditional_skip (ip, value == 0, T_IF, NULL_PTR, op);
- return 0;
-}
-
-/* Handle a #elif directive by not changing if_stack either.
- see the comment above do_else. */
-
-static int
-do_elif (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- HOST_WIDEST_INT value;
- FILE_BUF *ip = &instack[indepth];
-
- if (if_stack == instack[indepth].if_stack) {
- error ("`#elif' not within a conditional");
- return 0;
- } else {
- if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
- error ("`#elif' after `#else'");
- fprintf (stderr, " (matches line %d", if_stack->lineno);
- if (! (if_stack->fname_len == ip->nominal_fname_len
- && !bcmp (if_stack->fname, ip->nominal_fname,
- if_stack->fname_len))) {
- fprintf (stderr, ", file ");
- fwrite (if_stack->fname, sizeof if_stack->fname[0],
- if_stack->fname_len, stderr);
- }
- fprintf (stderr, ")\n");
- }
- if_stack->type = T_ELIF;
- }
-
- if (if_stack->if_succeeded)
- skip_if_group (ip, 0, op);
- else {
- value = eval_if_expression (buf, limit - buf);
- if (value == 0)
- skip_if_group (ip, 0, op);
- else {
- ++if_stack->if_succeeded; /* continue processing input */
- output_line_directive (ip, op, 1, same_file);
- }
- }
- return 0;
-}
-
-/* Evaluate a #if expression in BUF, of length LENGTH, then parse the
- result as a C expression and return the value as an int. */
-
-static HOST_WIDEST_INT
-eval_if_expression (buf, length)
- const U_CHAR *buf;
- int length;
-{
- FILE_BUF temp_obuf;
- HASHNODE *save_defined;
- HOST_WIDEST_INT value;
-
- save_defined = install ((const U_CHAR *) "defined", -1, T_SPEC_DEFINED,
- NULL_PTR, -1);
- pcp_inside_if = 1;
- temp_obuf = expand_to_temp_buffer (buf, buf + length, 0, 1);
- pcp_inside_if = 0;
- delete_macro (save_defined); /* clean up special symbol */
-
- *temp_obuf.bufp = '\n';
- value = parse_c_expression ((char *) temp_obuf.buf,
- warn_undef && !instack[indepth].system_header_p);
-
- free (temp_obuf.buf);
-
- return value;
-}
-
-/* routine to handle ifdef/ifndef. Try to look up the symbol, then do
- or don't skip to the #endif/#else/#elif depending on what directive
- is actually being processed. */
-
-static int
-do_xifdef (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword;
-{
- int skip;
- FILE_BUF *ip = &instack[indepth];
- U_CHAR *end;
- int start_of_file = 0;
- U_CHAR *control_macro = 0;
-
- /* Detect a #ifndef at start of file (not counting comments). */
- if (ip->fname != 0 && keyword->type == T_IFNDEF) {
- U_CHAR *p = ip->buf;
- while (p != directive_start) {
- U_CHAR c = *p++;
- if (is_space[c])
- ;
- /* Make no special provision for backslash-newline here; this is
- slower if backslash-newlines are present, but it's correct,
- and it's not worth it to tune for the rare backslash-newline. */
- else if (c == '/'
- && (*p == '*' || (cplusplus_comments && *p == '/'))) {
- /* Skip this comment. */
- int junk = 0;
- U_CHAR *save_bufp = ip->bufp;
- ip->bufp = p + 1;
- p = skip_to_end_of_comment (ip, &junk, 1);
- ip->bufp = save_bufp;
- } else {
- goto fail;
- }
- }
- /* If we get here, this conditional is the beginning of the file. */
- start_of_file = 1;
- fail: ;
- }
-
- /* Discard leading and trailing whitespace. */
- SKIP_WHITE_SPACE (buf);
- while (limit != buf && is_hor_space[limit[-1]]) limit--;
-
- /* Find the end of the identifier at the beginning. */
- for (end = buf; is_idchar[*end]; end++);
-
- if (end == buf) {
- skip = (keyword->type == T_IFDEF);
- if (! traditional)
- {
- if (end == limit)
- pedwarn ("`#%s' with no argument", keyword->name);
- else
- pedwarn ("`#%s' argument starts with punctuation", keyword->name);
- }
- } else {
- HASHNODE *hp;
-
- if (! traditional) {
- if (ISDIGIT (buf[0]))
- pedwarn ("`#%s' argument starts with a digit", keyword->name);
- else if (end != limit)
- pedwarn ("garbage at end of `#%s' argument", keyword->name);
- }
-
- hp = lookup (buf, end-buf, -1);
-
- if (pcp_outfile) {
- /* Output a precondition for this macro. */
- if (hp
- && (hp->type == T_CONST
- || (hp->type == T_MACRO && hp->value.defn->predefined)))
- fprintf (pcp_outfile, "#define %s\n", hp->name);
- else {
- U_CHAR *cp = buf;
- fprintf (pcp_outfile, "#undef ");
- while (is_idchar[*cp]) /* Ick! */
- fputc (*cp++, pcp_outfile);
- putc ('\n', pcp_outfile);
- }
- }
-
- if ((hp != NULL) && (hp->type == T_POISON)) {
- error("attempt to use poisoned `%s'.", hp->name);
- hp = NULL;
- }
- skip = (hp == NULL) ^ (keyword->type == T_IFNDEF);
- if (start_of_file && !skip) {
- control_macro = (U_CHAR *) xmalloc (end - buf + 1);
- bcopy ((const PTR) buf, (PTR) control_macro, end - buf);
- control_macro[end - buf] = 0;
- }
- }
-
- conditional_skip (ip, skip, T_IF, control_macro, op);
- return 0;
-}
-
-/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
- If this is a #ifndef starting at the beginning of a file,
- CONTROL_MACRO is the macro name tested by the #ifndef.
- Otherwise, CONTROL_MACRO is 0. */
-
-static void
-conditional_skip (ip, skip, type, control_macro, op)
- FILE_BUF *ip;
- int skip;
- enum node_type type;
- const U_CHAR *control_macro;
- FILE_BUF *op;
-{
- IF_STACK_FRAME *temp;
-
- temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
- temp->fname = ip->nominal_fname;
- temp->fname_len = ip->nominal_fname_len;
- temp->lineno = ip->lineno;
- temp->next = if_stack;
- temp->control_macro = control_macro;
- if_stack = temp;
-
- if_stack->type = type;
-
- if (skip != 0) {
- skip_if_group (ip, 0, op);
- return;
- } else {
- ++if_stack->if_succeeded;
- output_line_directive (ip, &outbuf, 1, same_file);
- }
-}
-
-/* Skip to #endif, #else, or #elif. adjust line numbers, etc.
- Leaves input ptr at the sharp sign found.
- If ANY is nonzero, return at next directive of any sort. */
-
-static void
-skip_if_group (ip, any, op)
- FILE_BUF *ip;
- int any;
- FILE_BUF *op;
-{
- register U_CHAR *bp = ip->bufp, *cp;
- register U_CHAR *endb = ip->buf + ip->length;
- struct directive *kt;
- IF_STACK_FRAME *save_if_stack = if_stack; /* don't pop past here */
- U_CHAR *beg_of_line = bp;
- register int ident_length;
- U_CHAR *ident, *after_ident;
- /* Save info about where the group starts. */
- U_CHAR *beg_of_group = bp;
- int beg_lineno = ip->lineno;
- int skipping_include_directive = 0;
-
- if (output_conditionals && op != 0) {
- static const char * const ptr = "#failed\n";
- int len = strlen (ptr);
-
- if (op->bufp > op->buf && op->bufp[-1] != '\n')
- {
- *op->bufp++ = '\n';
- op->lineno++;
- }
- check_expand (op, len);
- bcopy (ptr, (char *) op->bufp, len);
- op->bufp += len;
- op->lineno++;
- output_line_directive (ip, op, 1, 0);
- }
-
- while (bp < endb) {
- switch (*bp++) {
- case '/': /* possible comment */
- if (*bp == '\\')
- newline_fix (bp);
- if (*bp == '*'
- || (cplusplus_comments && *bp == '/')) {
- ip->bufp = ++bp;
- bp = skip_to_end_of_comment (ip, &ip->lineno, 0);
- }
- break;
- case '<':
- if (skipping_include_directive) {
- while (bp < endb && *bp != '>' && *bp != '\n') {
- if (*bp == '\\' && bp[1] == '\n') {
- ip->lineno++;
- bp++;
- }
- bp++;
- }
- }
- break;
- case '\"':
- if (skipping_include_directive) {
- while (bp < endb && *bp != '\n') {
- if (*bp == '"') {
- bp++;
- break;
- }
- if (*bp == '\\' && bp[1] == '\n') {
- ip->lineno++;
- bp++;
- }
- bp++;
- }
- break;
- }
- /* Fall through. */
- case '\'':
- bp = skip_quoted_string (bp - 1, endb, ip->lineno, &ip->lineno,
- NULL_PTR, NULL_PTR);
- break;
- case '\\':
- /* Char after backslash loses its special meaning in some cases. */
- if (*bp == '\n') {
- ++ip->lineno;
- bp++;
- } else if (traditional && bp < endb)
- bp++;
- break;
- case '\n':
- ++ip->lineno;
- beg_of_line = bp;
- skipping_include_directive = 0;
- break;
- case '%':
- if (beg_of_line == 0 || traditional)
- break;
- ip->bufp = bp - 1;
- while (bp[0] == '\\' && bp[1] == '\n')
- bp += 2;
- if (*bp == ':')
- goto sharp_token;
- break;
- case '#':
- /* # keyword: a # must be first nonblank char on the line */
- if (beg_of_line == 0)
- break;
- ip->bufp = bp - 1;
- sharp_token:
- /* Scan from start of line, skipping whitespace, comments
- and backslash-newlines, and see if we reach this #.
- If not, this # is not special. */
- bp = beg_of_line;
- /* If -traditional, require # to be at beginning of line. */
- if (!traditional) {
- while (1) {
- if (is_hor_space[*bp])
- bp++;
- else if (*bp == '\\' && bp[1] == '\n')
- bp += 2;
- else if (*bp == '/' && bp[1] == '*') {
- bp += 2;
- while (1)
- {
- if (*bp == '*')
- {
- if (bp[1] == '/')
- {
- bp += 2;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, endb - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- bp++;
- }
- }
- /* There is no point in trying to deal with C++ // comments here,
- because if there is one, then this # must be part of the
- comment and we would never reach here. */
- else break;
- }
- }
- if (bp != ip->bufp) {
- bp = ip->bufp + 1; /* Reset bp to after the #. */
- break;
- }
-
- bp = ip->bufp + 1; /* Point after the '#' */
- if (ip->bufp[0] == '%') {
- /* Skip past the ':' again. */
- while (*bp == '\\') {
- ip->lineno++;
- bp += 2;
- }
- bp++;
- }
-
- /* Skip whitespace and \-newline. */
- while (1) {
- if (is_hor_space[*bp])
- bp++;
- else if (*bp == '\\' && bp[1] == '\n')
- bp += 2;
- else if (*bp == '/') {
- if (bp[1] == '\\')
- newline_fix (bp + 1);
- if (bp[1] == '*') {
- for (bp += 2; ; bp++) {
- if (*bp == '\n')
- ip->lineno++;
- else if (*bp == '*') {
- if (bp[-1] == '/' && warn_comments)
- warning ("`/*' within comment");
- if (bp[1] == '\\')
- newline_fix (bp + 1);
- if (bp[1] == '/')
- break;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, endb - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- bp += 2;
- } else if (bp[1] == '/' && cplusplus_comments) {
- for (bp += 2; ; bp++) {
- if (*bp == '\n')
- break;
- if (*bp == '\\' && bp[1] == '\n')
- {
- if (warn_comments)
- warning ("multiline `//' comment");
- ip->lineno++;
- bp++;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, endb - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- } else
- break;
- } else
- break;
- }
-
- cp = bp;
-
- /* Now find end of directive name.
- If we encounter a backslash-newline, exchange it with any following
- symbol-constituents so that we end up with a contiguous name. */
-
- while (1) {
- if (is_idchar[*bp])
- bp++;
- else {
- if (*bp == '\\')
- name_newline_fix (bp);
- if (is_idchar[*bp])
- bp++;
- else break;
- }
- }
- ident_length = bp - cp;
- ident = cp;
- after_ident = bp;
-
- /* A line of just `#' becomes blank. */
-
- if (ident_length == 0 && *after_ident == '\n') {
- continue;
- }
-
- if (ident_length == 0 || !is_idstart[*ident]) {
- U_CHAR *p = ident;
- while (is_idchar[*p]) {
- if (*p < '0' || *p > '9')
- break;
- p++;
- }
- /* Handle # followed by a line number. */
- if (p != ident && !is_idchar[*p]) {
- if (pedantic)
- pedwarn ("`#' followed by integer");
- continue;
- }
-
- /* Avoid error for `###' and similar cases unless -pedantic. */
- if (p == ident) {
- while (*p == '#' || is_hor_space[*p]) p++;
- if (*p == '\n') {
- if (pedantic && !lang_asm)
- pedwarn ("invalid preprocessing directive");
- continue;
- }
- }
-
- if (!lang_asm && pedantic)
- pedwarn ("invalid preprocessing directive name");
- continue;
- }
-
- for (kt = directive_table; kt->length >= 0; kt++) {
- IF_STACK_FRAME *temp;
- if (ident_length == kt->length
- && bcmp (cp, kt->name, kt->length) == 0) {
- /* If we are asked to return on next directive, do so now. */
- if (any)
- goto done;
-
- switch (kt->type) {
- case T_IF:
- case T_IFDEF:
- case T_IFNDEF:
- temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
- temp->next = if_stack;
- if_stack = temp;
- temp->lineno = ip->lineno;
- temp->fname = ip->nominal_fname;
- temp->fname_len = ip->nominal_fname_len;
- temp->type = kt->type;
- break;
- case T_ELSE:
- case T_ENDIF:
- if (pedantic && if_stack != save_if_stack)
- validate_else (bp, endb);
- case T_ELIF:
- if (if_stack == instack[indepth].if_stack) {
- error ("`#%s' not within a conditional", kt->name);
- break;
- }
- else if (if_stack == save_if_stack)
- goto done; /* found what we came for */
-
- if (kt->type != T_ENDIF) {
- if (if_stack->type == T_ELSE)
- error ("`#else' or `#elif' after `#else'");
- if_stack->type = kt->type;
- break;
- }
-
- temp = if_stack;
- if_stack = if_stack->next;
- free (temp);
- break;
-
- case T_INCLUDE:
- case T_INCLUDE_NEXT:
- case T_IMPORT:
- skipping_include_directive = 1;
- break;
-
- default:
- break;
- }
- break;
- }
- }
- /* Don't let erroneous code go by. */
- if (kt->length < 0 && !lang_asm && pedantic)
- pedwarn ("invalid preprocessing directive name");
- }
- }
-
- ip->bufp = bp;
- /* after this returns, rescan will exit because ip->bufp
- now points to the end of the buffer.
- rescan is responsible for the error message also. */
-
- done:
- if (output_conditionals && op != 0) {
- static const char * const ptr = "#endfailed\n";
- int len = strlen (ptr);
-
- if (op->bufp > op->buf && op->bufp[-1] != '\n')
- {
- *op->bufp++ = '\n';
- op->lineno++;
- }
- check_expand (op, beg_of_line - beg_of_group);
- bcopy ((const PTR) beg_of_group, (PTR) op->bufp,
- beg_of_line - beg_of_group);
- op->bufp += beg_of_line - beg_of_group;
- op->lineno += ip->lineno - beg_lineno;
- check_expand (op, len);
- bcopy (ptr, (char *) op->bufp, len);
- op->bufp += len;
- op->lineno++;
- }
-}
-
-/* Handle a #else directive. Do this by just continuing processing
- without changing if_stack ; this is so that the error message
- for missing #endif's etc. will point to the original #if. It
- is possible that something different would be better. */
-
-static int
-do_else (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- FILE_BUF *ip = &instack[indepth];
-
- if (pedantic) {
- SKIP_WHITE_SPACE (buf);
- if (buf != limit)
- pedwarn ("text following `#else' violates ANSI standard");
- }
-
- if (if_stack == instack[indepth].if_stack) {
- error ("`#else' not within a conditional");
- return 0;
- } else {
- /* #ifndef can't have its special treatment for containing the whole file
- if it has a #else clause. */
- if_stack->control_macro = 0;
-
- if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
- error ("`#else' after `#else'");
- fprintf (stderr, " (matches line %d", if_stack->lineno);
- if (! (if_stack->fname_len == ip->nominal_fname_len
- && !bcmp (if_stack->fname, ip->nominal_fname,
- if_stack->fname_len))) {
- fprintf (stderr, ", file ");
- fwrite (if_stack->fname, sizeof if_stack->fname[0],
- if_stack->fname_len, stderr);
- }
- fprintf (stderr, ")\n");
- }
- if_stack->type = T_ELSE;
- }
-
- if (if_stack->if_succeeded)
- skip_if_group (ip, 0, op);
- else {
- ++if_stack->if_succeeded; /* continue processing input */
- output_line_directive (ip, op, 1, same_file);
- }
- return 0;
-}
-
-/* Unstack after #endif directive. */
-
-static int
-do_endif (buf, limit, op, keyword)
- U_CHAR *buf, *limit;
- FILE_BUF *op;
- struct directive *keyword ATTRIBUTE_UNUSED;
-{
- if (pedantic) {
- SKIP_WHITE_SPACE (buf);
- if (buf != limit)
- pedwarn ("text following `#endif' violates ANSI standard");
- }
-
- if (if_stack == instack[indepth].if_stack)
- error ("unbalanced `#endif'");
- else {
- IF_STACK_FRAME *temp = if_stack;
- if_stack = if_stack->next;
- if (temp->control_macro != 0) {
- /* This #endif matched a #ifndef at the start of the file.
- See if it is at the end of the file. */
- FILE_BUF *ip = &instack[indepth];
- U_CHAR *p = ip->bufp;
- U_CHAR *ep = ip->buf + ip->length;
-
- while (p != ep) {
- U_CHAR c = *p++;
- if (!is_space[c]) {
- if (c == '/'
- && (*p == '*' || (cplusplus_comments && *p == '/'))) {
- /* Skip this comment. */
- int junk = 0;
- U_CHAR *save_bufp = ip->bufp;
- ip->bufp = p + 1;
- p = skip_to_end_of_comment (ip, &junk, 1);
- ip->bufp = save_bufp;
- } else
- goto fail;
- }
- }
- /* If we get here, this #endif ends a #ifndef
- that contains all of the file (aside from whitespace).
- Arrange not to include the file again
- if the macro that was tested is defined.
-
- Do not do this for the top-level file in a -include or any
- file in a -imacros. */
- if (indepth != 0
- && ! (indepth == 1 && no_record_file)
- && ! (no_record_file && no_output))
- record_control_macro (ip->inc, temp->control_macro);
- fail: ;
- }
- free (temp);
- output_line_directive (&instack[indepth], op, 1, same_file);
- }
- return 0;
-}
-
-/* When an #else or #endif is found while skipping failed conditional,
- if -pedantic was specified, this is called to warn about text after
- the directive name. P points to the first char after the directive
- name. */
-
-static void
-validate_else (p, limit)
- register const U_CHAR *p;
- register const U_CHAR *limit;
-{
- /* Advance P over whitespace and comments. */
- while (1) {
- while (*p == '\\' && p[1] == '\n')
- p += 2;
- if (is_hor_space[*p])
- p++;
- else if (*p == '/') {
- while (p[1] == '\\' && p[2] == '\n')
- p += 2;
- if (p[1] == '*') {
- /* Don't bother warning about unterminated comments
- since that will happen later. Just be sure to exit. */
- for (p += 2; ; p++) {
- if (p == limit)
- return;
- if (*p == '*') {
- while (p[1] == '\\' && p[2] == '\n')
- p += 2;
- if (p[1] == '/') {
- p += 2;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (p, limit - p);
- if (length > 1)
- p += (length - 1);
-#endif
- }
- }
- }
- else if (cplusplus_comments && p[1] == '/')
- return;
- else break;
- } else break;
- }
- if (*p != '\n')
- pedwarn ("text following `#else' or `#endif' violates ANSI standard");
-}
-
-/* Skip a comment, assuming the input ptr immediately follows the
- initial slash-star. Bump *LINE_COUNTER for each newline.
- (The canonical line counter is &ip->lineno.)
- Don't use this routine (or the next one) if bumping the line
- counter is not sufficient to deal with newlines in the string.
-
- If NOWARN is nonzero, don't warn about slash-star inside a comment.
- This feature is useful when processing a comment that is going to
- be processed or was processed at another point in the preprocessor,
- to avoid a duplicate warning. Likewise for unterminated comment
- errors. */
-
-static U_CHAR *
-skip_to_end_of_comment (ip, line_counter, nowarn)
- register FILE_BUF *ip;
- int *line_counter; /* place to remember newlines, or NULL */
- int nowarn;
-{
- register U_CHAR *limit = ip->buf + ip->length;
- register U_CHAR *bp = ip->bufp;
- FILE_BUF *op = put_out_comments && !line_counter ? &outbuf : (FILE_BUF *) 0;
- int start_line = line_counter ? *line_counter : 0;
-
- /* JF this line_counter stuff is a crock to make sure the
- comment is only put out once, no matter how many times
- the comment is skipped. It almost works */
- if (op) {
- *op->bufp++ = '/';
- *op->bufp++ = bp[-1];
- }
- if (cplusplus_comments && bp[-1] == '/') {
- for (; bp < limit; bp++) {
- if (*bp == '\n')
- break;
- if (*bp == '\\' && bp + 1 < limit && bp[1] == '\n')
- {
- if (!nowarn && warn_comments)
- warning ("multiline `//' comment");
- if (line_counter)
- ++*line_counter;
- if (op)
- {
- ++op->lineno;
- *op->bufp++ = *bp;
- }
- ++bp;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- {
- if (op)
- {
- bcopy (bp, op->bufp, length - 1);
- op->bufp += (length - 1);
- }
- bp += (length - 1);
- }
-#endif
- }
- if (op)
- *op->bufp++ = *bp;
- }
- ip->bufp = bp;
- return bp;
- }
- while (bp < limit) {
- if (op)
- *op->bufp++ = *bp;
- switch (*bp++) {
- case '\n':
- /* If this is the end of the file, we have an unterminated comment.
- Don't swallow the newline. We are guaranteed that there will be a
- trailing newline and various pieces assume it's there. */
- if (bp == limit)
- {
- --bp;
- --limit;
- break;
- }
- if (line_counter != NULL)
- ++*line_counter;
- if (op)
- ++op->lineno;
- break;
- case '*':
- if (bp[-2] == '/' && !nowarn && warn_comments)
- warning ("`/*' within comment");
- if (*bp == '\\')
- newline_fix (bp);
- if (*bp == '/') {
- if (op)
- *op->bufp++ = '/';
- ip->bufp = ++bp;
- return bp;
- }
- break;
-#ifdef MULTIBYTE_CHARS
- default:
- {
- int length;
- bp--;
- length = local_mblen (bp, limit - bp);
- if (length <= 0)
- length = 1;
- if (op)
- {
- op->bufp--;
- bcopy (bp, op->bufp, length);
- op->bufp += length;
- }
- bp += length;
- }
-#endif
- }
- }
-
- if (!nowarn)
- error_with_line (line_for_error (start_line), "unterminated comment");
- ip->bufp = bp;
- return bp;
-}
-
-/* Skip over a quoted string. BP points to the opening quote.
- Returns a pointer after the closing quote. Don't go past LIMIT.
- START_LINE is the line number of the starting point (but it need
- not be valid if the starting point is inside a macro expansion).
-
- The input stack state is not changed.
-
- If COUNT_NEWLINES is nonzero, it points to an int to increment
- for each newline passed; also, warn about any white space
- just before line end.
-
- If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it
- if we pass a backslash-newline.
-
- If EOFP is nonzero, set *EOFP to 1 if the string is unterminated. */
-
-static U_CHAR *
-skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp)
- register const U_CHAR *bp;
- register const U_CHAR *limit;
- int start_line;
- int *count_newlines;
- int *backslash_newlines_p;
- int *eofp;
-{
- register U_CHAR c, match;
-
- match = *bp++;
- while (1) {
- if (bp >= limit) {
- error_with_line (line_for_error (start_line),
- "unterminated string or character constant");
- error_with_line (multiline_string_line,
- "possible real start of unterminated constant");
- multiline_string_line = 0;
- if (eofp)
- *eofp = 1;
- break;
- }
- c = *bp++;
- if (c == '\\') {
- while (*bp == '\\' && bp[1] == '\n') {
- if (backslash_newlines_p)
- *backslash_newlines_p = 1;
- if (count_newlines)
- ++*count_newlines;
- bp += 2;
- }
- if (*bp == '\n') {
- if (backslash_newlines_p)
- *backslash_newlines_p = 1;
- if (count_newlines)
- ++*count_newlines;
- }
- bp++;
- } else if (c == '\n') {
- if (traditional) {
- /* Unterminated strings and character constants are 'valid'. */
- bp--; /* Don't consume the newline. */
- if (eofp)
- *eofp = 1;
- break;
- }
- if (match == '\'') {
- error_with_line (line_for_error (start_line),
- "unterminated character constant");
- bp--;
- if (eofp)
- *eofp = 1;
- break;
- }
- /* If not traditional, then allow newlines inside strings. */
- if (count_newlines) {
- if (warn_white_space && is_hor_space[bp[-2]])
- warning ("white space at end of line in string");
- ++*count_newlines;
- }
- if (multiline_string_line == 0) {
- if (pedantic)
- pedwarn_with_line (line_for_error (start_line),
- "string constant runs past end of line");
- multiline_string_line = start_line;
- }
- } else if (c == match)
- break;
-#ifdef MULTIBYTE_CHARS
- {
- int length;
- --bp;
- length = local_mblen (bp, limit - bp);
- if (length <= 0)
- length = 1;
- bp += length;
- }
-#endif
- }
- return (U_CHAR *) bp;
-}
-
-/* Place into DST a quoted string representing the string SRC.
- SRCLEN is the length of SRC; SRC may contain null bytes.
- Return the address of DST's terminating null. */
-
-static char *
-quote_string (dst, src, srclen)
- char *dst;
- const char *src;
- size_t srclen;
-{
- U_CHAR c;
- const char *srclim = src + srclen;
-
- *dst++ = '\"';
- while (src != srclim)
- switch ((c = *src++))
- {
- default:
- if (ISPRINT (c))
- *dst++ = c;
- else
- {
- sprintf (dst, "\\%03o", c);
- dst += 4;
- }
- break;
-
- case '\"':
- case '\\':
- *dst++ = '\\';
- *dst++ = c;
- break;
- }
-
- *dst++ = '\"';
- *dst = '\0';
- return dst;
-}
-
-/* Skip across a group of balanced parens, starting from IP->bufp.
- IP->bufp is updated. Use this with IP->bufp pointing at an open-paren.
-
- This does not handle newlines, because it's used for the arg of #if,
- where there aren't any newlines. Also, backslash-newline can't appear. */
-
-static U_CHAR *
-skip_paren_group (ip)
- register FILE_BUF *ip;
-{
- U_CHAR *limit = ip->buf + ip->length;
- U_CHAR *p = ip->bufp;
- int depth = 0;
- int lines_dummy = 0;
-
- while (p != limit) {
- int c = *p++;
- switch (c) {
- case '(':
- depth++;
- break;
-
- case ')':
- depth--;
- if (depth == 0)
- return ip->bufp = p;
- break;
-
- case '/':
- if (*p == '*') {
- ip->bufp = p;
- p = skip_to_end_of_comment (ip, &lines_dummy, 0);
- p = ip->bufp;
- }
-
- case '"':
- case '\'':
- {
- int eofp = 0;
- p = skip_quoted_string (p - 1, limit, 0, NULL_PTR, NULL_PTR, &eofp);
- if (eofp)
- return ip->bufp = p;
- }
- break;
- }
- }
-
- ip->bufp = p;
- return p;
-}
-
-/* Write out a #line directive, for instance, after an #include file.
- If CONDITIONAL is nonzero, we can omit the #line if it would
- appear to be a no-op, and we can output a few newlines instead
- if we want to increase the line number by a small amount.
- FILE_CHANGE says whether we are entering a file, leaving, or neither. */
-
-static void
-output_line_directive (ip, op, conditional, file_change)
- FILE_BUF *ip, *op;
- int conditional;
- enum file_change_code file_change;
-{
- int len;
- char *line_directive_buf, *line_end;
-
- if (no_line_directives
- || ip->fname == NULL
- || no_output) {
- op->lineno = ip->lineno;
- return;
- }
-
- if (conditional) {
- if (ip->lineno == op->lineno)
- return;
-
- /* If the inherited line number is a little too small,
- output some newlines instead of a #line directive. */
- if (ip->lineno > op->lineno && ip->lineno < op->lineno + 8) {
- check_expand (op, 10);
- while (ip->lineno > op->lineno) {
- *op->bufp++ = '\n';
- op->lineno++;
- }
- return;
- }
- }
-
- /* Output a positive line number if possible. */
- while (ip->lineno <= 0 && ip->bufp - ip->buf < ip->length
- && *ip->bufp == '\n') {
- ip->lineno++;
- ip->bufp++;
- }
-
- line_directive_buf = (char *) alloca (4 * ip->nominal_fname_len + 100);
- sprintf (line_directive_buf, "# %d ", ip->lineno);
- line_end = quote_string (line_directive_buf + strlen (line_directive_buf),
- ip->nominal_fname, ip->nominal_fname_len);
- if (file_change != same_file) {
- *line_end++ = ' ';
- *line_end++ = file_change == enter_file ? '1' : '2';
- }
- /* Tell cc1 if following text comes from a system header file. */
- if (ip->system_header_p) {
- *line_end++ = ' ';
- *line_end++ = '3';
- }
-#ifndef NO_IMPLICIT_EXTERN_C
- /* Tell cc1plus if following text should be treated as C. */
- if (ip->system_header_p == 2 && cplusplus) {
- *line_end++ = ' ';
- *line_end++ = '4';
- }
-#endif
- *line_end++ = '\n';
- len = line_end - line_directive_buf;
- check_expand (op, len + 1);
- if (op->bufp > op->buf && op->bufp[-1] != '\n')
- *op->bufp++ = '\n';
- bcopy ((const PTR) line_directive_buf, (PTR) op->bufp, len);
- op->bufp += len;
- op->lineno = ip->lineno;
-}
-
-/* This structure represents one parsed argument in a macro call.
- `raw' points to the argument text as written (`raw_length' is its length).
- `expanded' points to the argument's macro-expansion
- (its length is `expand_length', and its allocated size is `expand_size').
- `stringified_length_bound' is an upper bound on the length
- the argument would have if stringified.
- `use_count' is the number of times this macro arg is substituted
- into the macro. If the actual use count exceeds 10,
- the value stored is 10.
- `free1' and `free2', if nonzero, point to blocks to be freed
- when the macro argument data is no longer needed.
- `free_ptr', if nonzero, points to a value of instack[i].free_ptr
- where the raw field points somewhere into this string. The purpose
- of this is to hold onto instack[i].buf for macro arguments, even
- when the element has been popped off the input stack.
-*/
-
-struct argdata {
- U_CHAR *raw, *expanded;
- int raw_length, expand_length, expand_size;
- int stringified_length_bound;
- U_CHAR *free1, *free2;
- U_CHAR *free_ptr;
- int newlines;
- char use_count;
-};
-
-/* Expand a macro call.
- HP points to the symbol that is the macro being called.
- Put the result of expansion onto the input stack
- so that subsequent input by our caller will use it.
-
- If macro wants arguments, caller has already verified that
- an argument list follows; arguments come from the input stack. */
-
-static void
-macroexpand (hp, op)
- HASHNODE *hp;
- FILE_BUF *op;
-{
- int nargs;
- DEFINITION *defn = hp->value.defn;
- register U_CHAR *xbuf;
- int xbuf_len;
- int start_line = instack[indepth].lineno;
- int rest_args, rest_zero;
-
- CHECK_DEPTH (return;);
-
- /* it might not actually be a macro. */
- if (hp->type != T_MACRO) {
- special_symbol (hp, op);
- return;
- }
-
- /* This macro is being used inside a #if, which means it must be */
- /* recorded as a precondition. */
- if (pcp_inside_if && pcp_outfile && defn->predefined)
- dump_single_macro (hp, pcp_outfile);
-
- nargs = defn->nargs;
-
- if (nargs >= 0) {
- register int i;
- struct argdata *args;
- int parse_error = 0;
-
- args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
-
- for (i = 0; i < nargs; i++) {
- args[i].raw = (U_CHAR *) "";
- args[i].expanded = 0;
- args[i].raw_length = args[i].expand_length = args[i].expand_size
- = args[i].stringified_length_bound = 0;
- args[i].free1 = args[i].free2 = 0;
- args[i].free_ptr = 0;
- args[i].use_count = 0;
- }
-
- /* Parse all the macro args that are supplied. I counts them.
- The first NARGS args are stored in ARGS.
- The rest are discarded.
- If rest_args is set then we assume macarg absorbed the rest of the args.
- */
- i = 0;
- rest_args = 0;
- do {
- /* Discard the open-parenthesis or comma before the next arg. */
- ++instack[indepth].bufp;
- if (rest_args)
- continue;
- if (i < nargs || (nargs == 0 && i == 0)) {
- /* If we are working on last arg which absorbs rest of args... */
- if (i == nargs - 1 && defn->rest_args)
- rest_args = 1;
- parse_error = macarg (&args[i], rest_args);
- }
- else
- parse_error = macarg (NULL_PTR, 0);
- if (parse_error) {
- error_with_line (line_for_error (start_line),
- "unterminated macro call");
- break;
- }
- i++;
- } while (*instack[indepth].bufp != ')');
-
- /* If we got one arg but it was just whitespace, call that 0 args. */
- if (i == 1) {
- register const U_CHAR *bp = args[0].raw;
- register const U_CHAR *lim = bp + args[0].raw_length;
- /* cpp.texi says for foo ( ) we provide one argument.
- However, if foo wants just 0 arguments, treat this as 0. */
- if (nargs == 0)
- while (bp != lim && is_space[*bp]) bp++;
- if (bp == lim)
- i = 0;
- }
-
- /* Don't output an error message if we have already output one for
- a parse error above. */
- rest_zero = 0;
- if (nargs == 0 && i > 0) {
- if (! parse_error)
- error ("arguments given to macro `%s'", hp->name);
- } else if (i < nargs) {
- /* traditional C allows foo() if foo wants one argument. */
- if (nargs == 1 && i == 0 && traditional)
- ;
- /* the rest args token is allowed to absorb 0 tokens */
- else if (i == nargs - 1 && defn->rest_args)
- rest_zero = 1;
- else if (parse_error)
- ;
- else if (i == 0)
- error ("macro `%s' used without args", hp->name);
- else if (i == 1)
- error ("macro `%s' used with just one arg", hp->name);
- else
- error ("macro `%s' used with only %d args", hp->name, i);
- } else if (i > nargs) {
- if (! parse_error)
- error ("macro `%s' used with too many (%d) args", hp->name, i);
- }
-
- /* Swallow the closeparen. */
- ++instack[indepth].bufp;
-
- /* If macro wants zero args, we parsed the arglist for checking only.
- Read directly from the macro definition. */
- if (nargs == 0) {
- xbuf = defn->expansion;
- xbuf_len = defn->length;
- } else {
- register U_CHAR *exp = defn->expansion;
- register int offset; /* offset in expansion,
- copied a piece at a time */
- register int totlen; /* total amount of exp buffer filled so far */
-
- register struct reflist *ap, *last_ap;
-
- /* Macro really takes args. Compute the expansion of this call. */
-
- /* Compute length in characters of the macro's expansion.
- Also count number of times each arg is used. */
- xbuf_len = defn->length;
- for (ap = defn->pattern; ap != NULL; ap = ap->next) {
- if (ap->stringify && args[ap->argno].stringified_length_bound == 0)
- /* macarg is not called for omitted arguments, as a result
- stringified_length_bound will be zero. We need to make
- enough space for "". */
- xbuf_len += 2;
- else if (ap->stringify)
- xbuf_len += args[ap->argno].stringified_length_bound;
- else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional)
- /* Add 4 for two newline-space markers to prevent
- token concatenation. */
- xbuf_len += args[ap->argno].raw_length + 4;
- else {
- /* We have an ordinary (expanded) occurrence of the arg.
- So compute its expansion, if we have not already. */
- if (args[ap->argno].expanded == 0) {
- FILE_BUF obuf;
- obuf = expand_to_temp_buffer (args[ap->argno].raw,
- args[ap->argno].raw + args[ap->argno].raw_length,
- 1, 0);
-
- args[ap->argno].expanded = obuf.buf;
- args[ap->argno].expand_length = obuf.bufp - obuf.buf;
- args[ap->argno].expand_size = obuf.length;
- args[ap->argno].free2 = obuf.buf;
-
- xbuf_len += args[ap->argno].expand_length;
- } else {
- /* If the arg appears more than once, its later occurrences
- may have newline turned into backslash-'n', which is a
- factor of 2 expansion. */
- xbuf_len += 2 * args[ap->argno].expand_length;
- }
- /* Add 4 for two newline-space markers to prevent
- token concatenation. */
- xbuf_len += 4;
- }
- if (args[ap->argno].use_count < 10)
- args[ap->argno].use_count++;
- }
-
- xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
-
- /* Generate in XBUF the complete expansion
- with arguments substituted in.
- TOTLEN is the total size generated so far.
- OFFSET is the index in the definition
- of where we are copying from. */
- offset = totlen = 0;
- for (last_ap = NULL, ap = defn->pattern; ap != NULL;
- last_ap = ap, ap = ap->next) {
- register struct argdata *arg = &args[ap->argno];
- int count_before = totlen;
-
- /* Add chars to XBUF. */
- for (i = 0; i < ap->nchars; i++, offset++)
- xbuf[totlen++] = exp[offset];
-
- /* If followed by an empty rest arg with concatenation,
- delete the last run of nonwhite chars. */
- if (rest_zero && totlen > count_before
- && ((ap->rest_args && ap->raw_before != 0)
- || (last_ap != NULL && last_ap->rest_args
- && last_ap->raw_after != 0))) {
- /* Delete final whitespace. */
- while (totlen > count_before && is_space[xbuf[totlen - 1]]) {
- totlen--;
- }
-
- /* Delete the nonwhites before them. */
- while (totlen > count_before && ! is_space[xbuf[totlen - 1]]) {
- totlen--;
- }
- }
-
- if (ap->stringify != 0) {
- int arglen = arg->raw_length;
- int escaped = 0;
- int in_string = 0;
- int c;
- i = 0;
- while (i < arglen
- && (c = arg->raw[i], is_space[c]))
- i++;
- while (i < arglen
- && (c = arg->raw[arglen - 1], is_space[c]))
- arglen--;
- if (!traditional)
- xbuf[totlen++] = '\"'; /* insert beginning quote */
- for (; i < arglen; i++) {
- c = arg->raw[i];
-
- if (in_string) {
- /* Generate nothing for backslash-newline in a string. */
- if (c == '\\' && arg->raw[i + 1] == '\n') {
- i++;
- continue;
- }
- } else {
- /* Special markers
- generate nothing for a stringified argument. */
- if (c == '\n') {
- i++;
- continue;
- }
-
- /* Internal sequences of whitespace are replaced by one space
- except within a string or char token. */
- if (is_space[c]) {
- i++;
- while (is_space[(c = arg->raw[i])])
- /* Newline markers can occur within a whitespace sequence;
- consider them part of the sequence. */
- i += (c == '\n') + 1;
- i--;
- c = ' ';
- }
- }
-
- if (escaped)
- escaped = 0;
- else {
- if (c == '\\')
- escaped = 1;
- else if (in_string) {
- if (c == in_string)
- in_string = 0;
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (arg->raw + i, arglen - i);
- if (length > 1)
- {
- bcopy (arg->raw + i, xbuf + totlen, length);
- i += length - 1;
- totlen += length;
- continue;
- }
-#endif
- }
- } else if (c == '\"' || c == '\'')
- in_string = c;
- }
-
- /* Escape double-quote, and backslashes in strings.
- Newlines in strings are best escaped as \n, since
- otherwise backslash-backslash-newline-newline is
- mishandled. The C Standard doesn't allow newlines in
- strings, so we can escape newlines as we please. */
- if (c == '\"'
- || (in_string
- && (c == '\\'
- || (c == '\n' ? (c = 'n', 1) : 0))))
- xbuf[totlen++] = '\\';
- /* We used to output e.g. \008 for control characters here,
- but this doesn't conform to the C Standard.
- Just output the characters as-is. */
- xbuf[totlen++] = c;
- }
- if (!traditional)
- xbuf[totlen++] = '\"'; /* insert ending quote */
- } else if (ap->raw_before != 0 || ap->raw_after != 0 || traditional) {
- const U_CHAR *p1 = arg->raw;
- const U_CHAR *l1 = p1 + arg->raw_length;
- if (ap->raw_before != 0) {
- while (p1 != l1 && is_space[*p1]) p1++;
- while (p1 != l1 && is_idchar[*p1])
- xbuf[totlen++] = *p1++;
- /* Delete any no-reexpansion marker that follows
- an identifier at the beginning of the argument
- if the argument is concatenated with what precedes it. */
- if (p1[0] == '\n' && p1[1] == '-')
- p1 += 2;
- } else if (!traditional) {
- /* Ordinary expanded use of the argument.
- Put in newline-space markers to prevent token pasting. */
- xbuf[totlen++] = '\n';
- xbuf[totlen++] = ' ';
- }
- if (ap->raw_after != 0) {
- /* Arg is concatenated after: delete trailing whitespace,
- whitespace markers, and no-reexpansion markers. */
- while (p1 != l1) {
- if (is_space[l1[-1]]) l1--;
- else if (l1[-1] == '-') {
- const U_CHAR *p2 = l1 - 1;
- /* If a `-' is preceded by an odd number of newlines then it
- and the last newline are a no-reexpansion marker. */
- while (p2 != p1 && p2[-1] == '\n') p2--;
- if ((l1 - 1 - p2) & 1) {
- l1 -= 2;
- }
- else break;
- }
- else break;
- }
- }
-
- bcopy ((const PTR) p1, (PTR) (xbuf + totlen), l1 - p1);
- totlen += l1 - p1;
- if (!traditional && ap->raw_after == 0) {
- /* Ordinary expanded use of the argument.
- Put in newline-space markers to prevent token pasting. */
- xbuf[totlen++] = '\n';
- xbuf[totlen++] = ' ';
- }
- } else {
- /* Ordinary expanded use of the argument.
- Put in newline-space markers to prevent token pasting. */
- if (!traditional) {
- xbuf[totlen++] = '\n';
- xbuf[totlen++] = ' ';
- }
- bcopy ((const PTR) arg->expanded, (PTR) (xbuf + totlen),
- arg->expand_length);
- totlen += arg->expand_length;
- if (!traditional) {
- xbuf[totlen++] = '\n';
- xbuf[totlen++] = ' ';
- }
- /* If a macro argument with newlines is used multiple times,
- then only expand the newlines once. This avoids creating output
- lines which don't correspond to any input line, which confuses
- gdb and gcov. */
- if (arg->use_count > 1 && arg->newlines > 0) {
- /* Don't bother doing change_newlines for subsequent
- uses of arg. */
- arg->use_count = 1;
- change_newlines (arg);
- }
- }
-
- if (totlen > xbuf_len)
- abort ();
- }
-
- /* If there is anything left of the definition after handling
- the arg list, copy that in too. */
-
- for (i = offset; i < defn->length; i++) {
- /* if we've reached the end of the macro */
- if (exp[i] == ')')
- rest_zero = 0;
- if (! (rest_zero && last_ap != NULL && last_ap->rest_args
- && last_ap->raw_after != 0))
- xbuf[totlen++] = exp[i];
- }
-
- xbuf[totlen] = 0;
- xbuf_len = totlen;
-
- for (i = 0; i < nargs; i++) {
- if (args[i].free_ptr != 0) {
- U_CHAR *buf = args[i].free_ptr;
- int d;
- for (d = indepth; d >= 0; --d) {
- if (instack[d].buf == buf) {
- instack[d].free_ptr = buf; /* Give ownership back to instack */
- goto no_free;
- }
- }
- free (buf); /* buf is not on the stack; must have been popped */
- no_free:;
- }
- if (args[i].free1 != 0)
- free (args[i].free1);
- if (args[i].free2 != 0)
- free (args[i].free2);
- }
- }
- } else {
- xbuf = defn->expansion;
- xbuf_len = defn->length;
- }
-
- /* Now put the expansion on the input stack
- so our caller will commence reading from it. */
- {
- register FILE_BUF *ip2;
-
- ip2 = &instack[++indepth];
-
- ip2->fname = 0;
- ip2->nominal_fname = 0;
- ip2->nominal_fname_len = 0;
- ip2->inc = 0;
- /* This may not be exactly correct, but will give much better error
- messages for nested macro calls than using a line number of zero. */
- ip2->lineno = start_line;
- ip2->buf = xbuf;
- ip2->length = xbuf_len;
- ip2->bufp = xbuf;
- ip2->free_ptr = (nargs > 0) ? xbuf : 0;
- ip2->macro = hp;
- ip2->if_stack = if_stack;
- ip2->system_header_p = 0;
-
- /* Recursive macro use sometimes works traditionally.
- #define foo(x,y) bar (x (y,0), y)
- foo (foo, baz) */
-
- if (!traditional)
- hp->type = T_DISABLED;
- }
-}
-
-/* Parse a macro argument and store the info on it into *ARGPTR.
- REST_ARGS is passed to macarg1 to make it absorb the rest of the args.
- Return nonzero to indicate a syntax error. */
-
-static int
-macarg (argptr, rest_args)
- register struct argdata *argptr;
- int rest_args;
-{
- FILE_BUF *ip = &instack[indepth];
- int paren = 0;
- int lineno0 = ip->lineno;
- int comments = 0;
- int result = 0;
-
- /* Try to parse as much of the argument as exists at this
- input stack level. */
- U_CHAR *bp = macarg1 (ip->bufp, ip->buf + ip->length, ip->macro,
- &paren, &ip->lineno, &comments, rest_args);
-
- /* If we find the end of the argument at this level,
- set up *ARGPTR to point at it in the input stack. */
- if (!(ip->fname != 0 && (ip->lineno != lineno0 || comments != 0))
- && bp != ip->buf + ip->length) {
- if (argptr != 0) {
- argptr->raw = ip->bufp;
- argptr->raw_length = bp - ip->bufp;
- argptr->newlines = ip->lineno - lineno0;
- /* The next two statements transfer ownership of the the buffer
- from ip to argptr. Note that the second statement ensures that
- a given free_ptr is owned by at most one macro argument. */
- argptr->free_ptr = ip->free_ptr;
- ip->free_ptr = 0;
- }
- ip->bufp = bp;
- } else {
- /* This input stack level ends before the macro argument does.
- We must pop levels and keep parsing.
- Therefore, we must allocate a temporary buffer and copy
- the macro argument into it. */
- int bufsize = bp - ip->bufp;
- int extra = ip->lineno - lineno0;
- U_CHAR *buffer = (U_CHAR *) xmalloc (bufsize + extra + 1);
- int final_start = 0;
-
- bcopy ((const PTR) ip->bufp, (PTR) buffer, bufsize);
- ip->bufp = bp;
-
- while (bp == ip->buf + ip->length) {
- if (instack[indepth].macro == 0) {
- result = 1;
- break;
- }
- ip->macro->type = T_MACRO;
- if (ip->free_ptr)
- free (ip->free_ptr);
- ip = &instack[--indepth];
- lineno0 = ip->lineno;
- comments = 0;
- bp = macarg1 (ip->bufp, ip->buf + ip->length, ip->macro, &paren,
- &ip->lineno, &comments, rest_args);
- final_start = bufsize;
- bufsize += bp - ip->bufp;
- extra += ip->lineno - lineno0;
- buffer = (U_CHAR *) xrealloc (buffer, bufsize + extra + 1);
- bcopy ((const PTR) ip->bufp, (PTR) (buffer + bufsize - (bp - ip->bufp)),
- bp - ip->bufp);
- ip->bufp = bp;
- }
-
- /* Now, if arg is actually wanted, record its raw form,
- discarding comments and duplicating newlines in whatever
- part of it did not come from a macro expansion.
- EXTRA space has been preallocated for duplicating the newlines.
- FINAL_START is the index of the start of that part. */
- if (argptr != 0) {
- argptr->raw = buffer;
- argptr->raw_length = bufsize;
- argptr->free1 = buffer;
- argptr->newlines = ip->lineno - lineno0;
- if ((argptr->newlines || comments) && ip->fname != 0)
- argptr->raw_length
- = final_start +
- discard_comments (argptr->raw + final_start,
- argptr->raw_length - final_start,
- argptr->newlines);
- argptr->raw[argptr->raw_length] = 0;
- if (argptr->raw_length > bufsize + extra)
- abort ();
- }
- }
-
- /* If we are not discarding this argument,
- macroexpand it and compute its length as stringified.
- All this info goes into *ARGPTR. */
-
- if (argptr != 0) {
- register const U_CHAR *buf, *lim;
- register int totlen;
-
- buf = argptr->raw;
- lim = buf + argptr->raw_length;
-
- while (buf != lim && is_space[*buf])
- buf++;
- while (buf != lim && is_space[lim[-1]])
- lim--;
- totlen = traditional ? 0 : 2; /* Count opening and closing quote. */
- while (buf != lim) {
- register U_CHAR c = *buf++;
- totlen++;
- /* Internal sequences of whitespace are replaced by one space
- in most cases, but not always. So count all the whitespace
- in case we need to keep it all. */
-#if 0
- if (is_space[c])
- SKIP_ALL_WHITE_SPACE (buf);
- else
-#endif
- if (c == '\"' || c == '\\' || c == '\n') /* escape these chars */
- totlen++;
- }
- argptr->stringified_length_bound = totlen;
- }
- return result;
-}
-
-/* Scan text from START (inclusive) up to LIMIT (exclusive),
- taken from the expansion of MACRO,
- counting parens in *DEPTHPTR,
- and return if reach LIMIT
- or before a `)' that would make *DEPTHPTR negative
- or before a comma when *DEPTHPTR is zero.
- Single and double quotes are matched and termination
- is inhibited within them. Comments also inhibit it.
- Value returned is pointer to stopping place.
-
- Increment *NEWLINES each time a newline is passed.
- REST_ARGS notifies macarg1 that it should absorb the rest of the args.
- Set *COMMENTS to 1 if a comment is seen. */
-
-static U_CHAR *
-macarg1 (start, limit, macro, depthptr, newlines, comments, rest_args)
- U_CHAR *start;
- register const U_CHAR *limit;
- struct hashnode *macro;
- int *depthptr, *newlines, *comments;
- int rest_args;
-{
- register U_CHAR *bp = start;
-
- while (bp < limit) {
- switch (*bp) {
- case '(':
- (*depthptr)++;
- break;
- case ')':
- if (--(*depthptr) < 0)
- return bp;
- break;
- case '\\':
- /* Traditionally, backslash makes following char not special. */
- if (traditional && bp + 1 < limit && bp[1] != '\n')
- bp++;
- break;
- case '\n':
- ++*newlines;
- break;
- case '/':
- if (macro)
- break;
- if (bp[1] == '\\')
- newline_fix (bp + 1);
- if (bp[1] == '*') {
- *comments = 1;
- for (bp += 2; bp < limit; bp++) {
- if (*bp == '\n')
- ++*newlines;
- else if (*bp == '*') {
- if (bp[-1] == '/' && warn_comments)
- warning ("`/*' within comment");
- if (bp[1] == '\\')
- newline_fix (bp + 1);
- if (bp[1] == '/') {
- bp++;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- } else if (bp[1] == '/' && cplusplus_comments) {
- *comments = 1;
- for (bp += 2; bp < limit; bp++) {
- if (*bp == '\n') {
- ++*newlines;
- break;
- }
- if (*bp == '\\' && bp + 1 < limit && bp[1] == '\n')
- {
- ++*newlines;
- if (warn_comments)
- warning ("multiline `//' comment");
- ++bp;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- }
- break;
- case '\'':
- case '\"':
- {
- int quotec;
- for (quotec = *bp++; bp < limit && *bp != quotec; bp++) {
- if (*bp == '\\') {
- bp++;
- if (*bp == '\n')
- ++*newlines;
- while (*bp == '\\' && bp[1] == '\n') {
- bp += 2;
- ++*newlines;
- }
- } else if (*bp == '\n') {
- if (warn_white_space && is_hor_space[bp[-1]] && ! macro)
- warning ("white space at end of line in string");
- ++*newlines;
- if (quotec == '\'')
- break;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- length = local_mblen (bp, limit - bp);
- if (length > 1)
- bp += (length - 1);
-#endif
- }
- }
- }
- break;
- case ',':
- /* if we've returned to lowest level and we aren't absorbing all args */
- if ((*depthptr) == 0 && rest_args == 0)
- return bp;
- break;
- }
- bp++;
- }
-
- return bp;
-}
-
-/* Discard comments and duplicate newlines
- in the string of length LENGTH at START,
- except inside of string constants.
- The string is copied into itself with its beginning staying fixed.
-
- NEWLINES is the number of newlines that must be duplicated.
- We assume that that much extra space is available past the end
- of the string. */
-
-static int
-discard_comments (start, length, newlines)
- U_CHAR *start;
- int length;
- int newlines;
-{
- register U_CHAR *ibp;
- register U_CHAR *obp;
- register U_CHAR *limit;
- register int c;
-
- /* If we have newlines to duplicate, copy everything
- that many characters up. Then, in the second part,
- we will have room to insert the newlines
- while copying down.
- NEWLINES may actually be too large, because it counts
- newlines in string constants, and we don't duplicate those.
- But that does no harm. */
- if (newlines > 0) {
- ibp = start + length;
- obp = ibp + newlines;
- limit = start;
- while (limit != ibp)
- *--obp = *--ibp;
- }
-
- ibp = start + newlines;
- limit = start + length + newlines;
- obp = start;
-
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- switch (c) {
- case '\n':
- /* Duplicate the newline. */
- *obp++ = '\n';
- break;
-
- case '\\':
- if (*ibp == '\n') {
- obp--;
- ibp++;
- }
- break;
-
- case '/':
- if (*ibp == '\\')
- newline_fix (ibp);
- /* Delete any comment. */
- if (cplusplus_comments && ibp[0] == '/') {
- /* Comments are equivalent to spaces. */
- obp[-1] = ' ';
- ibp++;
- while (ibp < limit)
- {
- if (*ibp == '\n')
- break;
- if (*ibp == '\\' && ibp + 1 < limit && ibp[1] == '\n')
- ibp++;
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- ibp += (length - 1);
-#endif
- }
- ibp++;
- }
- break;
- }
- if (ibp[0] != '*' || ibp + 1 >= limit)
- break;
- /* Comments are equivalent to spaces.
- For -traditional, a comment is equivalent to nothing. */
- if (traditional)
- obp--;
- else
- obp[-1] = ' ';
- while (++ibp < limit) {
- if (ibp[0] == '*') {
- if (ibp[1] == '\\')
- newline_fix (ibp + 1);
- if (ibp[1] == '/') {
- ibp += 2;
- break;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- ibp += (length - 1);
-#endif
- }
- }
- break;
-
- case '\'':
- case '\"':
- /* Notice and skip strings, so that we don't
- think that comments start inside them,
- and so we don't duplicate newlines in them. */
- {
- int quotec = c;
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- if (c == quotec)
- break;
- if (c == '\n')
- {
- if (quotec == '\'')
- break;
- }
- else if (c == '\\') {
- if (ibp < limit && *ibp == '\n') {
- ibp++;
- obp--;
- } else {
- while (*ibp == '\\' && ibp[1] == '\n')
- ibp += 2;
- if (ibp < limit)
- *obp++ = *ibp++;
- }
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- ibp--;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- {
- obp--;
- bcopy (ibp, obp, length);
- ibp += length;
- obp += length;
- }
- else
- ibp++;
-#endif
- }
- }
- }
- break;
- }
- }
-
- return obp - start;
-}
-
-/* Turn newlines to spaces in the macro argument ARG.
- Remove backslash-newline from string constants,
- and turn other newlines in string constants to backslash-'n'. */
-
-static void
-change_newlines (arg)
- struct argdata *arg;
-{
- U_CHAR *start = arg->expanded;
- int length = arg->expand_length;
- register U_CHAR *ibp;
- register U_CHAR *obp;
- register const U_CHAR *limit;
- register int c;
-
- ibp = start;
- limit = start + length;
- obp = start;
-
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- switch (c) {
- case '\n':
- /* If this is a NEWLINE NEWLINE, then this is a real newline in the
- string. Skip past the newline and its duplicate.
- Put a space in the output. */
- if (*ibp == '\n')
- {
- ibp++;
- obp--;
- *obp++ = ' ';
- }
- break;
-
- case '\'':
- case '\"':
- /* Notice and skip strings, so that we don't delete newlines in them. */
- {
- int quotec = c;
- while (ibp < limit) {
- *obp++ = c = *ibp++;
- if (c == quotec)
- break;
- else if (c == '\\' && ibp < limit && *ibp == '\n')
- *obp++ = *ibp++;
- else if (c == '\n')
- {
- if (quotec == '\'')
- break;
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- int length;
- ibp--;
- length = local_mblen (ibp, limit - ibp);
- if (length > 1)
- {
- obp--;
- bcopy (ibp, obp, length);
- ibp += length;
- obp += length;
- }
- else
- ibp++;
-#endif
- }
- }
- }
- break;
- }
- }
-
- arg->expand_length = obp - arg->expanded;
-
- if (start != arg->expanded)
- free (start);
-}
-
-/* notice - output message to stderr */
-
-static void
-notice VPARAMS ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- vnotice (msgid, args);
- va_end (args);
-}
-
-static void
-vnotice (msgid, args)
- const char *msgid;
- va_list args;
-{
- vfprintf (stderr, _(msgid), args);
-}
-
-/* error - print error message and increment count of errors. */
-
-void
-error VPARAMS ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- verror (msgid, args);
- va_end (args);
-}
-
-void
-verror (msgid, args)
- const char *msgid;
- va_list args;
-{
- int i;
- FILE_BUF *ip = NULL;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
- ip->nominal_fname_len, stderr);
- fprintf (stderr, ":%d: ", ip->lineno);
- }
- vnotice (msgid, args);
- fprintf (stderr, "\n");
- errors++;
-}
-
-/* Error including a message from `errno'. */
-
-static void
-error_from_errno (name)
- const char *name;
-{
- int e = errno;
- int i;
- FILE_BUF *ip = NULL;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
- ip->nominal_fname_len, stderr);
- fprintf (stderr, ":%d: ", ip->lineno);
- }
-
- fprintf (stderr, "%s: %s\n", name, xstrerror (e));
-
- errors++;
-}
-
-/* Print error message but don't count it. */
-
-void
-warning VPARAMS ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- vwarning (msgid, args);
- va_end (args);
-}
-
-static void
-vwarning (msgid, args)
- const char *msgid;
- va_list args;
-{
- int i;
- FILE_BUF *ip = NULL;
-
- if (inhibit_warnings)
- return;
-
- if (warnings_are_errors)
- errors++;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
- ip->nominal_fname_len, stderr);
- fprintf (stderr, ":%d: ", ip->lineno);
- }
- notice ("warning: ");
- vnotice (msgid, args);
- fprintf (stderr, "\n");
-}
-
-static void
-error_with_line VPARAMS ((int line, const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- int line;
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- line = va_arg (args, int);
- msgid = va_arg (args, const char *);
-#endif
-
- verror_with_line (line, msgid, args);
- va_end (args);
-}
-
-
-static void
-verror_with_line (line, msgid, args)
- int line;
- const char *msgid;
- va_list args;
-{
- int i;
- FILE_BUF *ip = NULL;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
- ip->nominal_fname_len, stderr);
- fprintf (stderr, ":%d: ", line);
- }
- vnotice (msgid, args);
- fprintf (stderr, "\n");
- errors++;
-}
-
-static void
-warning_with_line VPARAMS ((int line, const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- int line;
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- line = va_arg (args, int);
- msgid = va_arg (args, const char *);
-#endif
-
- vwarning_with_line (line, msgid, args);
- va_end (args);
-}
-
-static void
-vwarning_with_line (line, msgid, args)
- int line;
- const char *msgid;
- va_list args;
-{
- int i;
- FILE_BUF *ip = NULL;
-
- if (inhibit_warnings)
- return;
-
- if (warnings_are_errors)
- errors++;
-
- print_containing_files ();
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- if (ip != NULL) {
- fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
- ip->nominal_fname_len, stderr);
- if (line)
- fprintf (stderr, ":%d: ", line);
- else
- fputs (": ", stderr);
- }
- notice ("warning: ");
- vnotice (msgid, args);
- fprintf (stderr, "\n");
-}
-
-/* Print an error message and maybe count it. */
-
-void
-pedwarn VPARAMS ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- if (pedantic_errors)
- verror (msgid, args);
- else
- vwarning (msgid, args);
- va_end (args);
-}
-
-void
-pedwarn_with_line VPARAMS ((int line, const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- int line;
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- line = va_arg (args, int);
- msgid = va_arg (args, const char *);
-#endif
-
- if (pedantic_errors)
- verror_with_line (line, msgid, args);
- else
- vwarning_with_line (line, msgid, args);
- va_end (args);
-}
-
-/* Report a warning (or an error if pedantic_errors)
- giving specified file name and line number, not current. */
-
-static void
-pedwarn_with_file_and_line VPARAMS ((const char *file, size_t file_len,
- int line, const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *file;
- size_t file_len;
- int line;
- const char * msgid;
-#endif
- va_list args;
-
- if (!pedantic_errors && inhibit_warnings)
- return;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- file = va_arg (args, const char *);
- file_len = va_arg (args, size_t);
- line = va_arg (args, int);
- msgid = va_arg (args, const char *);
-#endif
-
- if (file) {
- fwrite (file, sizeof file[0], file_len, stderr);
- fprintf (stderr, ":%d: ", line);
- }
- if (pedantic_errors)
- errors++;
- if (!pedantic_errors)
- notice ("warning: ");
- vnotice (msgid, args);
- va_end (args);
- fprintf (stderr, "\n");
-}
-
-static void
-pedwarn_strange_white_space (ch)
- int ch;
-{
- switch (ch)
- {
- case '\f': pedwarn ("formfeed in preprocessing directive"); break;
- case '\r': pedwarn ("carriage return in preprocessing directive"); break;
- case '\v': pedwarn ("vertical tab in preprocessing directive"); break;
- default: abort ();
- }
-}
-
-/* Print the file names and line numbers of the #include
- directives which led to the current file. */
-
-static void
-print_containing_files ()
-{
- FILE_BUF *ip = NULL;
- int i;
- int first = 1;
-
- /* If stack of files hasn't changed since we last printed
- this info, don't repeat it. */
- if (last_error_tick == input_file_stack_tick)
- return;
-
- for (i = indepth; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- break;
- }
-
- /* Give up if we don't find a source file. */
- if (ip == NULL)
- return;
-
- /* Find the other, outer source files. */
- for (i--; i >= 0; i--)
- if (instack[i].fname != NULL) {
- ip = &instack[i];
- if (first) {
- first = 0;
- notice ( "In file included from ");
- } else {
- notice (",\n from ");
- }
-
- fwrite (ip->nominal_fname, sizeof ip->nominal_fname[0],
- ip->nominal_fname_len, stderr);
- fprintf (stderr, ":%d", ip->lineno);
- }
- if (! first)
- fprintf (stderr, ":\n");
-
- /* Record we have printed the status as of this time. */
- last_error_tick = input_file_stack_tick;
-}
-
-/* Return the line at which an error occurred.
- The error is not necessarily associated with the current spot
- in the input stack, so LINE says where. LINE will have been
- copied from ip->lineno for the current input level.
- If the current level is for a file, we return LINE.
- But if the current level is not for a file, LINE is meaningless.
- In that case, we return the lineno of the innermost file. */
-
-static int
-line_for_error (line)
- int line;
-{
- int i;
- int line1 = line;
-
- for (i = indepth; i >= 0; ) {
- if (instack[i].fname != 0)
- return line1;
- i--;
- if (i < 0)
- return 0;
- line1 = instack[i].lineno;
- }
- abort ();
- /*NOTREACHED*/
- return 0;
-}
-
-/*
- * If OBUF doesn't have NEEDED bytes after OPTR, make it bigger.
- *
- * As things stand, nothing is ever placed in the output buffer to be
- * removed again except when it's KNOWN to be part of an identifier,
- * so flushing and moving down everything left, instead of expanding,
- * should work ok.
- */
-
-/* You might think void was cleaner for the return type,
- but that would get type mismatch in check_expand in strict ANSI. */
-
-static int
-grow_outbuf (obuf, needed)
- register FILE_BUF *obuf;
- register int needed;
-{
- register U_CHAR *p;
- int minsize;
-
- if (obuf->length - (obuf->bufp - obuf->buf) > needed)
- return 0;
-
- /* Make it at least twice as big as it is now. */
- obuf->length *= 2;
- /* Make it have at least 150% of the free space we will need. */
- minsize = (3 * needed) / 2 + (obuf->bufp - obuf->buf);
- if (minsize > obuf->length)
- obuf->length = minsize;
-
- p = (U_CHAR *) xrealloc (obuf->buf, obuf->length);
-
- obuf->bufp = p + (obuf->bufp - obuf->buf);
- obuf->buf = p;
-
- return 0;
-}
-
-/* Symbol table for macro names and special symbols */
-
-/*
- * install a name in the main hash table, even if it is already there.
- * name stops with first non alphanumeric, except leading '#'.
- * caller must check against redefinition if that is desired.
- * delete_macro () removes things installed by install () in fifo order.
- * this is important because of the `defined' special symbol used
- * in #if, and also if pushdef/popdef directives are ever implemented.
- *
- * If LEN is >= 0, it is the length of the name.
- * Otherwise, compute the length by scanning the entire name.
- *
- * If HASH is >= 0, it is the precomputed hash code.
- * Otherwise, compute the hash code.
- */
-
-static HASHNODE *
-install (name, len, type, value, hash)
- const U_CHAR *name;
- int len;
- enum node_type type;
- const char *value;
- int hash;
-{
- register HASHNODE *hp;
- register int i, bucket;
- register U_CHAR *p;
- register const U_CHAR *q;
-
- if (len < 0) {
- q = name;
- while (is_idchar[*q])
- q++;
- len = q - name;
- }
-
- if (hash < 0)
- hash = hashf (name, len, HASHSIZE);
-
- i = sizeof (HASHNODE) + len + 1;
- hp = (HASHNODE *) xmalloc (i);
- bucket = hash;
- hp->bucket_hdr = &hashtab[bucket];
- hp->next = hashtab[bucket];
- hashtab[bucket] = hp;
- hp->prev = NULL;
- if (hp->next != NULL)
- hp->next->prev = hp;
- hp->type = type;
- hp->length = len;
- hp->value.cpval = value;
- hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE);
- p = hp->name;
- q = name;
- for (i = 0; i < len; i++)
- *p++ = *q++;
- hp->name[len] = 0;
- return hp;
-}
-
-/*
- * find the most recent hash node for name "name" (ending with first
- * non-identifier char) installed by install
- *
- * If LEN is >= 0, it is the length of the name.
- * Otherwise, compute the length by scanning the entire name.
- *
- * If HASH is >= 0, it is the precomputed hash code.
- * Otherwise, compute the hash code.
- */
-
-HASHNODE *
-lookup (name, len, hash)
- const U_CHAR *name;
- int len;
- int hash;
-{
- register const U_CHAR *bp;
- register HASHNODE *bucket;
-
- if (len < 0) {
- for (bp = name; is_idchar[*bp]; bp++) ;
- len = bp - name;
- }
-
- if (hash < 0)
- hash = hashf (name, len, HASHSIZE);
-
- bucket = hashtab[hash];
- while (bucket) {
- if (bucket->length == len && bcmp (bucket->name, name, len) == 0)
- return bucket;
- bucket = bucket->next;
- }
- return NULL;
-}
-
-/*
- * Delete a hash node. Some weirdness to free junk from macros.
- * More such weirdness will have to be added if you define more hash
- * types that need it.
- */
-
-/* Note that the DEFINITION of a macro is removed from the hash table
- but its storage is not freed. This would be a storage leak
- except that it is not reasonable to keep undefining and redefining
- large numbers of macros many times.
- In any case, this is necessary, because a macro can be #undef'd
- in the middle of reading the arguments to a call to it.
- If #undef freed the DEFINITION, that would crash. */
-
-static void
-delete_macro (hp)
- HASHNODE *hp;
-{
-
- if (hp->prev != NULL)
- hp->prev->next = hp->next;
- if (hp->next != NULL)
- hp->next->prev = hp->prev;
-
- /* Make sure that the bucket chain header that the deleted guy was
- on points to the right thing afterwards. */
- if (hp == *hp->bucket_hdr)
- *hp->bucket_hdr = hp->next;
-
-#if 0
- if (hp->type == T_MACRO) {
- DEFINITION *d = hp->value.defn;
- struct reflist *ap, *nextap;
-
- for (ap = d->pattern; ap != NULL; ap = nextap) {
- nextap = ap->next;
- free (ap);
- }
- free (d);
- }
-#endif
- free (hp);
-}
-
-/*
- * return hash function on name. must be compatible with the one
- * computed a step at a time, elsewhere
- */
-
-static int
-hashf (name, len, hashsize)
- register const U_CHAR *name;
- register int len;
- int hashsize;
-{
- register int r = 0;
-
- while (len--)
- r = HASHSTEP (r, *name++);
-
- return MAKE_POS (r) % hashsize;
-}
-
-
-/* Dump the definition of a single macro HP to OF. */
-
-static void
-dump_single_macro (hp, of)
- register HASHNODE *hp;
- FILE *of;
-{
- register DEFINITION *defn = hp->value.defn;
- struct reflist *ap;
- int offset;
- int concat;
-
-
- /* Print the definition of the macro HP. */
-
- fprintf (of, "#define %s", hp->name);
-
- if (defn->nargs >= 0) {
- int i;
-
- fprintf (of, "(");
- for (i = 0; i < defn->nargs; i++) {
- dump_arg_n (defn, i, of);
- if (i + 1 < defn->nargs)
- fprintf (of, ", ");
- }
- fprintf (of, ")");
- }
-
- fprintf (of, " ");
-
- offset = 0;
- concat = 0;
- for (ap = defn->pattern; ap != NULL; ap = ap->next) {
- dump_defn_1 (defn->expansion, offset, ap->nchars, of);
- offset += ap->nchars;
- if (!traditional) {
- if (ap->nchars != 0)
- concat = 0;
- if (ap->stringify) {
- switch (ap->stringify) {
- case SHARP_TOKEN: fprintf (of, "#"); break;
- case WHITE_SHARP_TOKEN: fprintf (of, "# "); break;
- case PERCENT_COLON_TOKEN: fprintf (of, "%%:"); break;
- case WHITE_PERCENT_COLON_TOKEN: fprintf (of, "%%: "); break;
- default: abort ();
- }
- }
- if (ap->raw_before != 0) {
- if (concat) {
- switch (ap->raw_before) {
- case WHITE_SHARP_TOKEN:
- case WHITE_PERCENT_COLON_TOKEN:
- fprintf (of, " ");
- break;
- default:
- break;
- }
- } else {
- switch (ap->raw_before) {
- case SHARP_TOKEN: fprintf (of, "##"); break;
- case WHITE_SHARP_TOKEN: fprintf (of, "## "); break;
- case PERCENT_COLON_TOKEN: fprintf (of, "%%:%%:"); break;
- case WHITE_PERCENT_COLON_TOKEN: fprintf (of, "%%:%%: "); break;
- default: abort ();
- }
- }
- }
- concat = 0;
- }
- dump_arg_n (defn, ap->argno, of);
- if (!traditional && ap->raw_after != 0) {
- switch (ap->raw_after) {
- case SHARP_TOKEN: fprintf (of, "##"); break;
- case WHITE_SHARP_TOKEN: fprintf (of, " ##"); break;
- case PERCENT_COLON_TOKEN: fprintf (of, "%%:%%:"); break;
- case WHITE_PERCENT_COLON_TOKEN: fprintf (of, " %%:%%:"); break;
- default: abort ();
- }
- concat = 1;
- }
- }
- dump_defn_1 (defn->expansion, offset, defn->length - offset, of);
- fprintf (of, "\n");
-}
-
-/* Dump all macro definitions as #defines to stdout. */
-
-static void
-dump_all_macros ()
-{
- int bucket;
-
- for (bucket = 0; bucket < HASHSIZE; bucket++) {
- register HASHNODE *hp;
-
- for (hp = hashtab[bucket]; hp; hp= hp->next) {
- if (hp->type == T_MACRO)
- dump_single_macro (hp, stdout);
- }
- }
-}
-
-/* Output to OF a substring of a macro definition.
- BASE is the beginning of the definition.
- Output characters START thru LENGTH.
- Unless traditional, discard newlines outside of strings, thus
- converting funny-space markers to ordinary spaces. */
-
-static void
-dump_defn_1 (base, start, length, of)
- const U_CHAR *base;
- int start;
- int length;
- FILE *of;
-{
- const U_CHAR *p = base + start;
- const U_CHAR *limit = base + start + length;
-
- if (traditional)
- fwrite (p, sizeof (*p), length, of);
- else {
- while (p < limit) {
- if (*p == '\"' || *p =='\'') {
- const U_CHAR *p1 = skip_quoted_string (p, limit, 0, NULL_PTR,
- NULL_PTR, NULL_PTR);
- fwrite (p, sizeof (*p), p1 - p, of);
- p = p1;
- } else {
- if (*p != '\n')
- putc (*p, of);
- p++;
- }
- }
- }
-}
-
-/* Print the name of argument number ARGNUM of macro definition DEFN
- to OF.
- Recall that DEFN->args.argnames contains all the arg names
- concatenated in reverse order with comma-space in between. */
-
-static void
-dump_arg_n (defn, argnum, of)
- DEFINITION *defn;
- int argnum;
- FILE *of;
-{
- register U_CHAR *p = defn->args.argnames;
- while (argnum + 1 < defn->nargs) {
- p = (U_CHAR *) index ((char *) p, ' ') + 1;
- argnum++;
- }
-
- while (*p && *p != ',') {
- putc (*p, of);
- p++;
- }
-}
-
-/* Initialize syntactic classifications of characters. */
-
-static void
-initialize_char_syntax ()
-{
- register int i;
-
- /*
- * Set up is_idchar and is_idstart tables. These should be
- * faster than saying (is_alpha (c) || c == '_'), etc.
- * Set up these things before calling any routines tthat
- * refer to them.
- */
- for (i = 'a'; i <= 'z'; i++) {
- is_idchar[TOUPPER(i)] = 1;
- is_idchar[i] = 1;
- is_idstart[TOUPPER(i)] = 1;
- is_idstart[i] = 1;
- }
- for (i = '0'; i <= '9'; i++)
- is_idchar[i] = 1;
- is_idchar['_'] = 1;
- is_idstart['_'] = 1;
- is_idchar['$'] = 1;
- is_idstart['$'] = 1;
-
- /* horizontal space table */
- is_hor_space[' '] = 1;
- is_hor_space['\t'] = 1;
- is_hor_space['\v'] = 1;
- is_hor_space['\f'] = 1;
- is_hor_space['\r'] = 1;
-
- is_space[' '] = 1;
- is_space['\t'] = 1;
- is_space['\v'] = 1;
- is_space['\f'] = 1;
- is_space['\n'] = 1;
- is_space['\r'] = 1;
-}
-
-/* Initialize the built-in macros. */
-
-static void
-initialize_builtins (inp, outp)
- FILE_BUF *inp;
- FILE_BUF *outp;
-{
- install ((const U_CHAR *) "__LINE__", -1, T_SPECLINE, NULL_PTR, -1);
- install ((const U_CHAR *) "__DATE__", -1, T_DATE, NULL_PTR, -1);
- install ((const U_CHAR *) "__FILE__", -1, T_FILE, NULL_PTR, -1);
- install ((const U_CHAR *) "__BASE_FILE__", -1, T_BASE_FILE, NULL_PTR, -1);
- install ((const U_CHAR *) "__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, NULL_PTR, -1);
- install ((const U_CHAR *) "__VERSION__", -1, T_VERSION, NULL_PTR, -1);
-#ifndef NO_BUILTIN_SIZE_TYPE
- install ((const U_CHAR *) "__SIZE_TYPE__", -1, T_SIZE_TYPE, NULL_PTR, -1);
-#endif
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
- install ((const U_CHAR *) "__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, NULL_PTR, -1);
-#endif
-#ifndef NO_BUILTIN_WCHAR_TYPE
- install ((const U_CHAR *) "__WCHAR_TYPE__", -1, T_WCHAR_TYPE, NULL_PTR, -1);
-#endif
- install ((const U_CHAR *) "__USER_LABEL_PREFIX__", -1, T_USER_LABEL_PREFIX_TYPE,
- NULL_PTR, -1);
- install ((const U_CHAR *) "__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE,
- NULL_PTR, -1);
- install ((const U_CHAR *) "__IMMEDIATE_PREFIX__", -1, T_IMMEDIATE_PREFIX_TYPE,
- NULL_PTR, -1);
- install ((const U_CHAR *) "__TIME__", -1, T_TIME, NULL_PTR, -1);
- if (!traditional) {
- install ((const U_CHAR *) "__STDC__", -1, T_CONST, "1", -1);
- install ((const U_CHAR *) "__STDC_VERSION__", -1, T_CONST, "199409L", -1);
- }
-/* This is supplied using a -D by the compiler driver
- so that it is present only when truly compiling with GNU C. */
-/* install ((U_CHAR *) "__GNUC__", -1, T_CONST, "2", -1); */
- install ((const U_CHAR *) "__HAVE_BUILTIN_SETJMP__", -1, T_CONST, "1", -1);
-
- if (debug_output)
- {
- char directive[2048];
- U_CHAR *udirective = (U_CHAR *) directive;
- register struct directive *dp = &directive_table[0];
- struct tm *timebuf = timestamp ();
-
- sprintf (directive, " __BASE_FILE__ \"%s\"\n",
- instack[0].nominal_fname);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-
- sprintf (directive, " __VERSION__ \"%s\"\n", version_string);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-
-#ifndef NO_BUILTIN_SIZE_TYPE
- sprintf (directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-#endif
-
-#ifndef NO_BUILTIN_PTRDIFF_TYPE
- sprintf (directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-#endif
-
-#ifndef NO_BUILTIN_WCHAR_TYPE
- sprintf (directive, " __WCHAR_TYPE__ %s\n", wchar_type);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-#endif
-
- sprintf (directive, " __DATE__ \"%s %2d %4d\"\n",
- monthnames[timebuf->tm_mon],
- timebuf->tm_mday, timebuf->tm_year + 1900);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-
- sprintf (directive, " __TIME__ \"%02d:%02d:%02d\"\n",
- timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec);
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
-
- if (!traditional)
- {
- sprintf (directive, " __STDC__ 1");
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
- }
- if (objc)
- {
- sprintf (directive, " __OBJC__ 1");
- output_line_directive (inp, outp, 0, same_file);
- pass_thru_directive (udirective, &udirective[strlen (directive)],
- outp, dp);
- }
- }
-}
-
-/*
- * process a given definition string, for initialization
- * If STR is just an identifier, define it with value 1.
- * If STR has anything after the identifier, then it should
- * be identifier=definition.
- */
-
-static void
-make_definition (str)
- char *str;
-{
- FILE_BUF *ip;
- struct directive *kt;
- U_CHAR *buf, *p;
-
- p = buf = (U_CHAR *) str;
- if (!is_idstart[*p]) {
- error ("malformed option `-D %s'", str);
- return;
- }
- while (is_idchar[*++p])
- ;
- if (*p == '(') {
- while (is_idchar[*++p] || *p == ',' || is_hor_space[*p])
- ;
- if (*p++ != ')')
- p = (U_CHAR *) str; /* Error */
- }
- if (*p == 0) {
- buf = (U_CHAR *) alloca (p - buf + 4);
- strcpy ((char *)buf, str);
- strcat ((char *)buf, " 1");
- } else if (*p != '=') {
- error ("malformed option `-D %s'", str);
- return;
- } else {
- U_CHAR *q;
- /* Copy the entire option so we can modify it. */
- buf = (U_CHAR *) alloca (2 * strlen (str) + 1);
- strncpy ((char *) buf, str, p - (U_CHAR *) str);
- /* Change the = to a space. */
- buf[p - (U_CHAR *) str] = ' ';
- /* Scan for any backslash-newline and remove it. */
- p++;
- q = &buf[p - (U_CHAR *) str];
- while (*p) {
- if (*p == '\"' || *p == '\'') {
- int unterminated = 0;
- const U_CHAR *p1 = skip_quoted_string (p, p + strlen ((char *) p), 0,
- NULL_PTR, NULL_PTR, &unterminated);
- if (unterminated)
- return;
- while (p != p1) {
- if (*p == '\\' && p[1] == '\n')
- p += 2;
- else if (*p == '\n')
- {
- *q++ = '\\';
- *q++ = 'n';
- p++;
- }
- else
- *q++ = *p++;
- }
- } else if (*p == '\\' && p[1] == '\n')
- p += 2;
- /* Change newline chars into newline-markers. */
- else if (*p == '\n')
- {
- *q++ = '\n';
- *q++ = '\n';
- p++;
- }
- else
- *q++ = *p++;
- }
- *q = 0;
- }
-
- ip = &instack[++indepth];
- ip->nominal_fname = ip->fname = "*Initialization*";
- ip->nominal_fname_len = strlen (ip->nominal_fname);
-
- ip->buf = ip->bufp = buf;
- ip->length = strlen ((char *) buf);
- ip->lineno = 1;
- ip->macro = 0;
- ip->free_ptr = 0;
- ip->if_stack = if_stack;
- ip->system_header_p = 0;
-
- for (kt = directive_table; kt->type != T_DEFINE; kt++)
- ;
-
- /* Pass NULL instead of OP, since this is a "predefined" macro. */
- do_define (buf, buf + strlen ((char *) buf), NULL_PTR, kt);
- --indepth;
-}
-
-/* JF, this does the work for the -U option */
-
-static void
-make_undef (str, op)
- char *str;
- FILE_BUF *op;
-{
- FILE_BUF *ip;
- struct directive *kt;
-
- ip = &instack[++indepth];
- ip->nominal_fname = ip->fname = "*undef*";
- ip->nominal_fname_len = strlen (ip->nominal_fname);
-
- ip->buf = ip->bufp = (U_CHAR *) str;
- ip->length = strlen (str);
- ip->lineno = 1;
- ip->macro = 0;
- ip->free_ptr = 0;
- ip->if_stack = if_stack;
- ip->system_header_p = 0;
-
- for (kt = directive_table; kt->type != T_UNDEF; kt++)
- ;
-
- do_undef ((U_CHAR *) str, (U_CHAR *) str + strlen (str), op, kt);
- --indepth;
-}
-
-/* Process the string STR as if it appeared as the body of a #assert.
- OPTION is the option name for which STR was the argument. */
-
-static void
-make_assertion (option, str)
- const char *option;
- const char *str;
-{
- FILE_BUF *ip;
- struct directive *kt;
- U_CHAR *buf, *p, *q;
-
- /* Copy the entire option so we can modify it. */
- buf = (U_CHAR *) alloca (strlen (str) + 1);
- strcpy ((char *) buf, str);
- /* Scan for any backslash-newline and remove it. */
- p = q = buf;
- while (*p) {
- if (*p == '\\' && p[1] == '\n')
- p += 2;
- else
- *q++ = *p++;
- }
- *q = 0;
-
- p = buf;
- if (!is_idstart[*p]) {
- error ("malformed option `%s %s'", option, str);
- return;
- }
- while (is_idchar[*++p])
- ;
- SKIP_WHITE_SPACE (p);
- if (! (*p == 0 || *p == '(')) {
- error ("malformed option `%s %s'", option, str);
- return;
- }
-
- ip = &instack[++indepth];
- ip->nominal_fname = ip->fname = "*Initialization*";
- ip->nominal_fname_len = strlen (ip->nominal_fname);
-
- ip->buf = ip->bufp = buf;
- ip->length = strlen ((char *) buf);
- ip->lineno = 1;
- ip->macro = 0;
- ip->free_ptr = 0;
- ip->if_stack = if_stack;
- ip->system_header_p = 0;
-
- for (kt = directive_table; kt->type != T_ASSERT; kt++)
- ;
-
- /* Pass NULL as output ptr to do_define since we KNOW it never does
- any output.... */
- do_assert (buf, buf + strlen ((char *) buf) , NULL_PTR, kt);
- --indepth;
-}
-
-/* The previous include prefix, if any, is PREV_FILE_NAME.
- Translate any pathnames with COMPONENT.
- Allocate a new include prefix whose name is the
- simplified concatenation of PREFIX and NAME,
- with a trailing / added if needed.
- But return 0 if the include prefix should be ignored,
- e.g. because it is a duplicate of PREV_FILE_NAME. */
-
-static struct file_name_list *
-new_include_prefix (prev_file_name, component, prefix, name)
- struct file_name_list *prev_file_name;
- const char *component;
- const char *prefix;
- const char *name;
-{
- if (name == 0)
- fatal ("Directory name missing after command line option");
-
- if (*name == 0)
- /* Ignore the empty string. */
- return 0;
-
- prefix = update_path (prefix, component);
- name = update_path (name, component);
-
- {
- struct file_name_list *dir
- = ((struct file_name_list *)
- xmalloc (sizeof (struct file_name_list)
- + strlen (prefix) + strlen (name) + 2));
- size_t len;
- strcpy (dir->fname, prefix);
- strcat (dir->fname, name);
- len = simplify_filename (dir->fname);
-
- /* Convert directory name to a prefix. */
- if (len && dir->fname[len - 1] != DIR_SEPARATOR) {
- if (len == 1 && dir->fname[len - 1] == '.')
- len = 0;
- else
-#ifdef VMS
- /* must be '/', hack_vms_include_specification triggers on it. */
- dir->fname[len++] = '/';
-#else
- dir->fname[len++] = DIR_SEPARATOR;
-#endif
- dir->fname[len] = 0;
- }
-
- /* Ignore a directory whose name matches the previous one. */
- if (prev_file_name && !strcmp (prev_file_name->fname, dir->fname)) {
- /* But treat `-Idir -I- -Idir' as `-I- -Idir'. */
- if (!first_bracket_include)
- first_bracket_include = prev_file_name;
- free (dir);
- return 0;
- }
-
-#ifndef VMS
- /* VMS can't stat dir prefixes, so skip these optimizations in VMS. */
-
- /* Add a trailing "." if there is a filename. This increases the number
- of systems that can stat directories. We remove it below. */
- if (len != 0)
- {
- dir->fname[len] = '.';
- dir->fname[len + 1] = 0;
- }
-
- /* Ignore a nonexistent directory. */
- if (stat (len ? dir->fname : ".", &dir->st) != 0) {
- if (errno != ENOENT && errno != ENOTDIR)
- error_from_errno (dir->fname);
- free (dir);
- return 0;
- }
-
- if (len != 0)
- dir->fname[len] = 0;
-
- /* Ignore a directory whose identity matches the previous one. */
- if (prev_file_name
- && INO_T_EQ (prev_file_name->st.st_ino, dir->st.st_ino)
- && prev_file_name->st.st_dev == dir->st.st_dev) {
- /* But treat `-Idir -I- -Idir' as `-I- -Idir'. */
- if (!first_bracket_include)
- first_bracket_include = prev_file_name;
- free (dir);
- return 0;
- }
-#endif /* ! VMS */
-
- dir->next = 0;
- dir->c_system_include_path = 0;
- dir->got_name_map = 0;
-
- return dir;
- }
-}
-
-/* Append a chain of `struct file_name_list's
- to the end of the main include chain.
- FIRST is the beginning of the chain to append, and LAST is the end. */
-
-static void
-append_include_chain (first, last)
- struct file_name_list *first, *last;
-{
- struct file_name_list *dir;
-
- if (!first || !last)
- return;
-
- if (include == 0)
- include = first;
- else
- last_include->next = first;
-
- if (first_bracket_include == 0)
- first_bracket_include = first;
-
- for (dir = first; ; dir = dir->next) {
- int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
- if (len > max_include_len)
- max_include_len = len;
- if (dir == last)
- break;
- }
-
- last->next = NULL;
- last_include = last;
-}
-
-/* Place into DST a representation of the file named SRC that is suitable
- for `make'. Do not null-terminate DST. Return its length. */
-static int
-quote_string_for_make (dst, src)
- char *dst;
- const char *src;
-{
- const char *p = src;
- int i = 0;
- for (;;)
- {
- char c = *p++;
- switch (c)
- {
- case '\0':
- case ' ':
- case '\t':
- {
- /* GNU make uses a weird quoting scheme for white space.
- A space or tab preceded by 2N+1 backslashes represents
- N backslashes followed by space; a space or tab
- preceded by 2N backslashes represents N backslashes at
- the end of a file name; and backslashes in other
- contexts should not be doubled. */
- const char *q;
- for (q = p - 1; src < q && q[-1] == '\\'; q--)
- {
- if (dst)
- dst[i] = '\\';
- i++;
- }
- }
- if (!c)
- return i;
- if (dst)
- dst[i] = '\\';
- i++;
- goto ordinary_char;
-
- case '$':
- if (dst)
- dst[i] = c;
- i++;
- /* Fall through. This can mishandle things like "$(" but
- there's no easy fix. */
- default:
- ordinary_char:
- /* This can mishandle characters in the string "\0\n%*?[\\~";
- exactly which chars are mishandled depends on the `make' version.
- We know of no portable solution for this;
- even GNU make 3.76.1 doesn't solve the problem entirely.
- (Also, '\0' is mishandled due to our calling conventions.) */
- if (dst)
- dst[i] = c;
- i++;
- break;
- }
- }
-}
-
-
-/* Add output to `deps_buffer' for the -M switch.
- STRING points to the text to be output.
- SPACER is ':' for targets, ' ' for dependencies. */
-
-static void
-deps_output (string, spacer)
- const char *string;
- int spacer;
-{
- int size = quote_string_for_make ((char *) 0, string);
-
- if (size == 0)
- return;
-
-#ifndef MAX_OUTPUT_COLUMNS
-#define MAX_OUTPUT_COLUMNS 72
-#endif
- if (MAX_OUTPUT_COLUMNS - 1 /*spacer*/ - 2 /*` \'*/ < deps_column + size
- && 1 < deps_column) {
- bcopy (" \\\n ", &deps_buffer[deps_size], 4);
- deps_size += 4;
- deps_column = 1;
- if (spacer == ' ')
- spacer = 0;
- }
-
- if (deps_size + 2 * size + 8 > deps_allocated_size) {
- deps_allocated_size = (deps_size + 2 * size + 50) * 2;
- deps_buffer = xrealloc (deps_buffer, deps_allocated_size);
- }
- if (spacer == ' ') {
- deps_buffer[deps_size++] = ' ';
- deps_column++;
- }
- quote_string_for_make (&deps_buffer[deps_size], string);
- deps_size += size;
- deps_column += size;
- if (spacer == ':') {
- deps_buffer[deps_size++] = ':';
- deps_column++;
- }
- deps_buffer[deps_size] = 0;
-}
-
-void
-fatal VPARAMS ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- fprintf (stderr, "%s: ", progname);
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
- vnotice (msgid, args);
- va_end (args);
- fprintf (stderr, "\n");
- exit (FATAL_EXIT_CODE);
-}
-
-/* More 'friendly' abort that prints the line and file.
- config.h can #define abort fancy_abort if you like that sort of thing. */
-
-void
-fancy_abort ()
-{
- fatal ("Internal gcc abort.");
-}
-
-static void
-perror_with_name (name)
- const char *name;
-{
- fprintf (stderr, "%s: %s: %s\n", progname, name, xstrerror (errno));
- errors++;
-}
-
-static void
-pfatal_with_name (name)
- const char *name;
-{
- perror_with_name (name);
-#ifdef VMS
- exit (vaxc$errno);
-#else
- exit (FATAL_EXIT_CODE);
-#endif
-}
-
-/* Handler for SIGPIPE. */
-
-static void
-pipe_closed (signo)
- /* If this is missing, some compilers complain. */
- int signo ATTRIBUTE_UNUSED;
-{
- fatal ("output pipe has been closed");
-}
-
-static void
-memory_full ()
-{
- fatal ("Memory exhausted.");
-}
-
-#ifdef VMS
-
-/* Under VMS we need to fix up the "include" specification filename.
-
- Rules for possible conversions
-
- fullname tried paths
-
- name name
- ./dir/name [.dir]name
- /dir/name dir:name
- /name [000000]name, name
- dir/name dir:[000000]name, dir:name, dir/name
- dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
- path:/name path:[000000]name, path:name
- path:/dir/name path:[000000.dir]name, path:[dir]name
- path:dir/name path:[dir]name
- [path]:[dir]name [path.dir]name
- path/[dir]name [path.dir]name
-
- The path:/name input is constructed when expanding <> includes.
-
- return 1 if name was changed, 0 else. */
-
-static int
-hack_vms_include_specification (fullname, vaxc_include)
- char *fullname;
- int vaxc_include;
-{
- register char *basename, *unixname, *local_ptr, *first_slash;
- int f, check_filename_before_returning, must_revert;
- char Local[512];
-
- check_filename_before_returning = 0;
- must_revert = 0;
- /* See if we can find a 1st slash. If not, there's no path information. */
- first_slash = index (fullname, '/');
- if (first_slash == 0)
- return 0; /* Nothing to do!!! */
-
- /* construct device spec if none given. */
-
- if (index (fullname, ':') == 0)
- {
-
- /* If fullname has a slash, take it as device spec. */
-
- if (first_slash == fullname)
- {
- first_slash = index (fullname+1, '/'); /* 2nd slash ? */
- if (first_slash)
- *first_slash = ':'; /* make device spec */
- for (basename = fullname; *basename != 0; basename++)
- *basename = *(basename+1); /* remove leading slash */
- }
- else if ((first_slash[-1] != '.') /* keep ':/', './' */
- && (first_slash[-1] != ':')
- && (first_slash[-1] != ']')) /* or a vms path */
- {
- *first_slash = ':';
- }
- else if ((first_slash[1] == '[') /* skip './' in './[dir' */
- && (first_slash[-1] == '.'))
- fullname += 2;
- }
-
- /* Get part after first ':' (basename[-1] == ':')
- or last '/' (basename[-1] == '/'). */
-
- basename = base_name (fullname);
-
- /*
- * Check if we have a vax-c style '#include filename'
- * and add the missing .h
- */
-
- if (vaxc_include && !index (basename,'.'))
- strcat (basename, ".h");
-
- local_ptr = Local; /* initialize */
-
- /* We are trying to do a number of things here. First of all, we are
- trying to hammer the filenames into a standard format, such that later
- processing can handle them.
-
- If the file name contains something like [dir.], then it recognizes this
- as a root, and strips the ".]". Later processing will add whatever is
- needed to get things working properly.
-
- If no device is specified, then the first directory name is taken to be
- a device name (or a rooted logical). */
-
- /* Point to the UNIX filename part (which needs to be fixed!)
- but skip vms path information.
- [basename != fullname since first_slash != 0]. */
-
- if ((basename[-1] == ':') /* vms path spec. */
- || (basename[-1] == ']')
- || (basename[-1] == '>'))
- unixname = basename;
- else
- unixname = fullname;
-
- if (*unixname == '/')
- unixname++;
-
- /* If the directory spec is not rooted, we can just copy
- the UNIX filename part and we are done. */
-
- if (((basename - fullname) > 1)
- && ( (basename[-1] == ']')
- || (basename[-1] == '>')))
- {
- if (basename[-2] != '.')
- {
-
- /* The VMS part ends in a `]', and the preceding character is not a `.'.
- -> PATH]:/name (basename = '/name', unixname = 'name')
- We strip the `]', and then splice the two parts of the name in the
- usual way. Given the default locations for include files in cccp.c,
- we will only use this code if the user specifies alternate locations
- with the /include (-I) switch on the command line. */
-
- basename -= 1; /* Strip "]" */
- unixname--; /* backspace */
- }
- else
- {
-
- /* The VMS part has a ".]" at the end, and this will not do. Later
- processing will add a second directory spec, and this would be a syntax
- error. Thus we strip the ".]", and thus merge the directory specs.
- We also backspace unixname, so that it points to a '/'. This inhibits the
- generation of the 000000 root directory spec (which does not belong here
- in this case). */
-
- basename -= 2; /* Strip ".]" */
- unixname--; /* backspace */
- }
- }
-
- else
-
- {
-
- /* We drop in here if there is no VMS style directory specification yet.
- If there is no device specification either, we make the first dir a
- device and try that. If we do not do this, then we will be essentially
- searching the users default directory (as if they did a #include "asdf.h").
-
- Then all we need to do is to push a '[' into the output string. Later
- processing will fill this in, and close the bracket. */
-
- if ((unixname != fullname) /* vms path spec found. */
- && (basename[-1] != ':'))
- *local_ptr++ = ':'; /* dev not in spec. take first dir */
-
- *local_ptr++ = '['; /* Open the directory specification */
- }
-
- if (unixname == fullname) /* no vms dir spec. */
- {
- must_revert = 1;
- if ((first_slash != 0) /* unix dir spec. */
- && (*unixname != '/') /* not beginning with '/' */
- && (*unixname != '.')) /* or './' or '../' */
- *local_ptr++ = '.'; /* dir is local ! */
- }
-
- /* at this point we assume that we have the device spec, and (at least
- the opening "[" for a directory specification. We may have directories
- specified already.
-
- If there are no other slashes then the filename will be
- in the "root" directory. Otherwise, we need to add
- directory specifications. */
-
- if (index (unixname, '/') == 0)
- {
- /* if no directories specified yet and none are following. */
- if (local_ptr[-1] == '[')
- {
- /* Just add "000000]" as the directory string */
- strcpy (local_ptr, "000000]");
- local_ptr += strlen (local_ptr);
- check_filename_before_returning = 1; /* we might need to fool with this later */
- }
- }
- else
- {
-
- /* As long as there are still subdirectories to add, do them. */
- while (index (unixname, '/') != 0)
- {
- /* If this token is "." we can ignore it
- if it's not at the beginning of a path. */
- if ((unixname[0] == '.') && (unixname[1] == '/'))
- {
- /* remove it at beginning of path. */
- if ( ((unixname == fullname) /* no device spec */
- && (fullname+2 != basename)) /* starts with ./ */
- /* or */
- || ((basename[-1] == ':') /* device spec */
- && (unixname-1 == basename))) /* and ./ afterwards */
- *local_ptr++ = '.'; /* make '[.' start of path. */
- unixname += 2;
- continue;
- }
-
- /* Add a subdirectory spec. Do not duplicate "." */
- if ( local_ptr[-1] != '.'
- && local_ptr[-1] != '['
- && local_ptr[-1] != '<')
- *local_ptr++ = '.';
-
- /* If this is ".." then the spec becomes "-" */
- if ( (unixname[0] == '.')
- && (unixname[1] == '.')
- && (unixname[2] == '/'))
- {
- /* Add "-" and skip the ".." */
- if ((local_ptr[-1] == '.')
- && (local_ptr[-2] == '['))
- local_ptr--; /* prevent [.- */
- *local_ptr++ = '-';
- unixname += 3;
- continue;
- }
-
- /* Copy the subdirectory */
- while (*unixname != '/')
- *local_ptr++= *unixname++;
-
- unixname++; /* Skip the "/" */
- }
-
- /* Close the directory specification */
- if (local_ptr[-1] == '.') /* no trailing periods */
- local_ptr--;
-
- if (local_ptr[-1] == '[') /* no dir needed */
- local_ptr--;
- else
- *local_ptr++ = ']';
- }
-
- /* Now add the filename. */
-
- while (*unixname)
- *local_ptr++ = *unixname++;
- *local_ptr = 0;
-
- /* Now append it to the original VMS spec. */
-
- strcpy ((must_revert==1)?fullname:basename, Local);
-
- /* If we put a [000000] in the filename, try to open it first. If this fails,
- remove the [000000], and return that name. This provides flexibility
- to the user in that they can use both rooted and non-rooted logical names
- to point to the location of the file. */
-
- if (check_filename_before_returning)
- {
- f = open (fullname, O_RDONLY, 0666);
- if (f >= 0)
- {
- /* The file name is OK as it is, so return it as is. */
- close (f);
- return 1;
- }
-
- /* The filename did not work. Try to remove the [000000] from the name,
- and return it. */
-
- basename = index (fullname, '[');
- local_ptr = index (fullname, ']') + 1;
- strcpy (basename, local_ptr); /* this gets rid of it */
-
- }
-
- return 1;
-}
-#endif /* VMS */
-
-#ifdef VMS
-
-/* The following wrapper functions supply additional arguments to the VMS
- I/O routines to optimize performance with file handling. The arguments
- are:
- "mbc=16" - Set multi-block count to 16 (use a 8192 byte buffer).
- "deq=64" - When extending the file, extend it in chunks of 32Kbytes.
- "fop=tef"- Truncate unused portions of file when closing file.
- "shr=nil"- Disallow file sharing while file is open. */
-
-static FILE *
-VMS_freopen (fname, type, oldfile)
- char *fname;
- char *type;
- FILE *oldfile;
-{
-#undef freopen /* Get back the real freopen routine. */
- if (strcmp (type, "w") == 0)
- return freopen (fname, type, oldfile,
- "mbc=16", "deq=64", "fop=tef", "shr=nil");
- return freopen (fname, type, oldfile, "mbc=16");
-}
-
-static FILE *
-VMS_fopen (fname, type)
- char *fname;
- char *type;
-{
-#undef fopen /* Get back the real fopen routine. */
- /* The gcc-vms-1.42 distribution's header files prototype fopen with two
- fixed arguments, which matches ANSI's specification but not VAXCRTL's
- pre-ANSI implementation. This hack circumvents the mismatch problem. */
- FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen;
-
- if (*type == 'w')
- return (*vmslib_fopen) (fname, type, "mbc=32",
- "deq=64", "fop=tef", "shr=nil");
- else
- return (*vmslib_fopen) (fname, type, "mbc=32");
-}
-
-static int
-VMS_open (fname, flags, prot)
- char *fname;
- int flags;
- int prot;
-{
-#undef open /* Get back the real open routine. */
- return open (fname, flags, prot, "mbc=16", "deq=64", "fop=tef");
-}
-
-/* more VMS hackery */
-#include <fab.h>
-#include <nam.h>
-
-extern unsigned long SYS$PARSE(), SYS$SEARCH();
-
-/* Work around another library bug. If a file is located via a searchlist,
- and if the device it's on is not the same device as the one specified
- in the first element of that searchlist, then both stat() and fstat()
- will fail to return info about it. `errno' will be set to EVMSERR, and
- `vaxc$errno' will be set to SS$_NORMAL due yet another bug in stat()!
- We can get around this by fully parsing the filename and then passing
- that absolute name to stat().
-
- Without this fix, we can end up failing to find header files, which is
- bad enough, but then compounding the problem by reporting the reason for
- failure as "normal successful completion." */
-
-#undef fstat /* Get back to the library version. */
-
-static int
-VMS_fstat (fd, statbuf)
- int fd;
- struct stat *statbuf;
-{
- int result = fstat (fd, statbuf);
-
- if (result < 0)
- {
- FILE *fp;
- char nambuf[NAM$C_MAXRSS+1];
-
- if ((fp = fdopen (fd, "r")) != 0 && fgetname (fp, nambuf) != 0)
- result = VMS_stat (nambuf, statbuf);
- /* No fclose(fp) here; that would close(fd) as well. */
- }
-
- return result;
-}
-
-static int
-VMS_stat (name, statbuf)
- const char *name;
- struct stat *statbuf;
-{
- int result = stat (name, statbuf);
-
- if (result < 0)
- {
- struct FAB fab;
- struct NAM nam;
- char exp_nam[NAM$C_MAXRSS+1], /* expanded name buffer for SYS$PARSE */
- res_nam[NAM$C_MAXRSS+1]; /* resultant name buffer for SYS$SEARCH */
-
- fab = cc$rms_fab;
- fab.fab$l_fna = (char *) name;
- fab.fab$b_fns = (unsigned char) strlen (name);
- fab.fab$l_nam = (void *) &nam;
- nam = cc$rms_nam;
- nam.nam$l_esa = exp_nam, nam.nam$b_ess = sizeof exp_nam - 1;
- nam.nam$l_rsa = res_nam, nam.nam$b_rss = sizeof res_nam - 1;
- nam.nam$b_nop = NAM$M_PWD | NAM$M_NOCONCEAL;
- if (SYS$PARSE (&fab) & 1)
- {
- if (SYS$SEARCH (&fab) & 1)
- {
- res_nam[nam.nam$b_rsl] = '\0';
- result = stat (res_nam, statbuf);
- }
- /* Clean up searchlist context cached by the system. */
- nam.nam$b_nop = NAM$M_SYNCHK;
- fab.fab$l_fna = 0, fab.fab$b_fns = 0;
- (void) SYS$PARSE (&fab);
- }
- }
-
- return result;
-}
-
-static size_t
-VMS_fwrite (ptr, size, nitems, stream)
- void const *ptr;
- size_t size;
- size_t nitems;
- FILE *stream;
-{
- /* VMS fwrite has undesirable results
- if STREAM happens to be a record oriented file.
- Work around this problem by writing each character individually. */
- char const *p = ptr;
- size_t bytes = size * nitems;
- char *lim = p + bytes;
-
- while (p < lim)
- if (putc (*p++, stream) == EOF)
- return 0;
-
- return bytes;
-}
-#endif /* VMS */
diff --git a/gcc/cexp.c b/gcc/cexp.c
deleted file mode 100644
index c278565931d..00000000000
--- a/gcc/cexp.c
+++ /dev/null
@@ -1,2206 +0,0 @@
-
-/* A Bison parser, made from cexp.y
- by GNU Bison version 1.28 */
-
-#define YYBISON 1 /* Identify Bison output. */
-
-#define INT 257
-#define CHAR 258
-#define NAME 259
-#define ERROR 260
-#define OR 261
-#define AND 262
-#define EQUAL 263
-#define NOTEQUAL 264
-#define LEQ 265
-#define GEQ 266
-#define LSH 267
-#define RSH 268
-#define UNARY 269
-
-#line 28 "cexp.y"
-
-#include "config.h"
-
-#include "system.h"
-#include "intl.h"
-#include <setjmp.h>
-/* #define YYDEBUG 1 */
-
-#ifdef MULTIBYTE_CHARS
-#include "mbchar.h"
-#include <locale.h>
-#endif /* MULTIBYTE_CHARS */
-
-typedef unsigned char U_CHAR;
-
-/* This is used for communicating lists of keywords with cccp.c. */
-struct arglist {
- struct arglist *next;
- U_CHAR *name;
- int length;
- int argno;
-};
-
-HOST_WIDEST_INT parse_c_expression PARAMS ((char *, int));
-
-static int yylex PARAMS ((void));
-static void yyerror PARAMS ((const char *, ...))
- ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-static HOST_WIDEST_INT expression_value;
-#ifdef TEST_EXP_READER
-static int expression_signedp;
-#endif
-
-static jmp_buf parse_return_error;
-
-/* Nonzero means count most punctuation as part of a name. */
-static int keyword_parsing = 0;
-
-/* Nonzero means do not evaluate this expression.
- This is a count, since unevaluated expressions can nest. */
-static int skip_evaluation;
-
-/* Nonzero means warn if undefined identifiers are evaluated. */
-static int warn_undef;
-
-/* some external tables of character types */
-extern unsigned char is_idstart[], is_idchar[], is_space[];
-
-/* Flag for -pedantic. */
-extern int pedantic;
-
-/* Flag for -traditional. */
-extern int traditional;
-
-/* Flag for -lang-c89. */
-extern int c89;
-
-#ifndef CHAR_TYPE_SIZE
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-#endif
-
-#ifndef INT_TYPE_SIZE
-#define INT_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef LONG_TYPE_SIZE
-#define LONG_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef WCHAR_TYPE_SIZE
-#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
-#endif
-
-#ifndef MAX_CHAR_TYPE_SIZE
-#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
-#endif
-
-#ifndef MAX_INT_TYPE_SIZE
-#define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
-#endif
-
-#ifndef MAX_LONG_TYPE_SIZE
-#define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
-#endif
-
-#ifndef MAX_WCHAR_TYPE_SIZE
-#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
-#endif
-
-#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
- ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
- : ~ (HOST_WIDEST_INT) 0)
-
-#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
- ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
- : ~ (HOST_WIDEST_INT) 0)
-
-/* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
- Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
- Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
- Then this yields nonzero if overflow occurred during the addition.
- Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
- and SIGNEDP is negative.
- Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
-#define overflow_sum_sign(a, b, sum, signedp) \
- ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
-
-struct constant;
-
-HOST_WIDEST_INT parse_escape PARAMS ((char **, HOST_WIDEST_INT));
-int check_assertion PARAMS ((U_CHAR *, int, int, struct arglist *));
-struct hashnode *lookup PARAMS ((U_CHAR *, int, int));
-void error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void verror PARAMS ((const char *, va_list));
-void pedwarn PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void warning PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-
-static int parse_number PARAMS ((int));
-static HOST_WIDEST_INT left_shift PARAMS ((struct constant *, unsigned HOST_WIDEST_INT));
-static HOST_WIDEST_INT right_shift PARAMS ((struct constant *, unsigned HOST_WIDEST_INT));
-static void integer_overflow PARAMS ((void));
-
-/* `signedp' values */
-#define SIGNED (~0)
-#define UNSIGNED 0
-
-#line 155 "cexp.y"
-typedef union {
- struct constant {HOST_WIDEST_INT value; int signedp;} integer;
- struct name {U_CHAR *address; int length;} name;
- struct arglist *keywords;
-} YYSTYPE;
-#include <stdio.h>
-
-#ifndef __cplusplus
-#ifndef __STDC__
-#define const
-#endif
-#endif
-
-
-
-#define YYFINAL 77
-#define YYFLAG -32768
-#define YYNTBASE 34
-
-#define YYTRANSLATE(x) ((unsigned)(x) <= 269 ? yytranslate[x] : 43)
-
-static const char yytranslate[] = { 0,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 29, 2, 31, 2, 27, 14, 2, 32,
- 33, 25, 23, 9, 24, 2, 26, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 8, 2, 17,
- 2, 18, 7, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 13, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 12, 2, 30, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
- 10, 11, 15, 16, 19, 20, 21, 22, 28
-};
-
-#if YYDEBUG != 0
-static const short yyprhs[] = { 0,
- 0, 2, 4, 8, 11, 14, 17, 20, 23, 24,
- 31, 35, 39, 43, 47, 51, 55, 59, 63, 67,
- 71, 75, 79, 83, 87, 91, 95, 99, 100, 105,
- 106, 111, 112, 113, 121, 123, 125, 127, 128, 133
-};
-
-static const short yyrhs[] = { 35,
- 0, 36, 0, 35, 9, 36, 0, 24, 36, 0,
- 29, 36, 0, 23, 36, 0, 30, 36, 0, 31,
- 5, 0, 0, 31, 5, 37, 32, 42, 33, 0,
- 32, 35, 33, 0, 36, 25, 36, 0, 36, 26,
- 36, 0, 36, 27, 36, 0, 36, 23, 36, 0,
- 36, 24, 36, 0, 36, 21, 36, 0, 36, 22,
- 36, 0, 36, 15, 36, 0, 36, 16, 36, 0,
- 36, 19, 36, 0, 36, 20, 36, 0, 36, 17,
- 36, 0, 36, 18, 36, 0, 36, 14, 36, 0,
- 36, 13, 36, 0, 36, 12, 36, 0, 0, 36,
- 11, 38, 36, 0, 0, 36, 10, 39, 36, 0,
- 0, 0, 36, 7, 40, 36, 8, 41, 36, 0,
- 3, 0, 4, 0, 5, 0, 0, 32, 42, 33,
- 42, 0, 5, 42, 0
-};
-
-#endif
-
-#if YYDEBUG != 0
-static const short yyrline[] = { 0,
- 185, 195, 196, 203, 208, 211, 213, 216, 220, 222,
- 227, 232, 245, 262, 275, 281, 287, 293, 299, 302,
- 305, 312, 319, 326, 333, 336, 339, 342, 345, 348,
- 351, 354, 356, 359, 362, 364, 366, 374, 376, 389
-};
-#endif
-
-
-#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
-
-static const char * const yytname[] = { "$","error","$undefined.","INT","CHAR",
-"NAME","ERROR","'?'","':'","','","OR","AND","'|'","'^'","'&'","EQUAL","NOTEQUAL",
-"'<'","'>'","LEQ","GEQ","LSH","RSH","'+'","'-'","'*'","'/'","'%'","UNARY","'!'",
-"'~'","'#'","'('","')'","start","exp1","exp","@1","@2","@3","@4","@5","keywords", NULL
-};
-#endif
-
-static const short yyr1[] = { 0,
- 34, 35, 35, 36, 36, 36, 36, 36, 37, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 38, 36, 39,
- 36, 40, 41, 36, 36, 36, 36, 42, 42, 42
-};
-
-static const short yyr2[] = { 0,
- 1, 1, 3, 2, 2, 2, 2, 2, 0, 6,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 0, 4, 0,
- 4, 0, 0, 7, 1, 1, 1, 0, 4, 2
-};
-
-static const short yydefact[] = { 0,
- 35, 36, 37, 0, 0, 0, 0, 0, 0, 1,
- 2, 6, 4, 5, 7, 8, 0, 0, 32, 30,
- 28, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 11, 3,
- 0, 0, 0, 27, 26, 25, 19, 20, 23, 24,
- 21, 22, 17, 18, 15, 16, 12, 13, 14, 38,
- 0, 31, 29, 38, 38, 0, 33, 40, 0, 10,
- 0, 38, 34, 39, 0, 0, 0
-};
-
-static const short yydefgoto[] = { 75,
- 10, 11, 38, 43, 42, 41, 71, 66
-};
-
-static const short yypact[] = { 12,
--32768,-32768,-32768, 12, 12, 12, 12, 1, 12, 4,
- 79,-32768,-32768,-32768,-32768, -21, 31, 12,-32768,-32768,
--32768, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 30,-32768, 79,
- 12, 12, 12, 110, 124, 137, 148, 148, 155, 155,
- 155, 155, 160, 160, -17, -17,-32768,-32768,-32768, 2,
- 58, 34, 95, 2, 2, 54,-32768,-32768, 55,-32768,
- 12, 2, 79,-32768, 63, 188,-32768
-};
-
-static const short yypgoto[] = {-32768,
- 180, -4,-32768,-32768,-32768,-32768,-32768, -60
-};
-
-
-#define YYLAST 189
-
-
-static const short yytable[] = { 12,
- 13, 14, 15, 68, 69, 16, 64, 35, 36, 37,
- -9, 74, 18, 40, 1, 2, 3, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 65, 4, 5, 61, 62, 63, 18,
- 6, 7, 8, 9, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 60, 76, 39, 19, 67, 73, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 19, 70, 72, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, 36, 37, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 31, 32, 33, 34, 35,
- 36, 37, 33, 34, 35, 36, 37, 77, 17
-};
-
-static const short yycheck[] = { 4,
- 5, 6, 7, 64, 65, 5, 5, 25, 26, 27,
- 32, 72, 9, 18, 3, 4, 5, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 32, 23, 24, 41, 42, 43, 9,
- 29, 30, 31, 32, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 32, 0, 33, 7, 8, 71, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 7, 33, 33, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 21, 22, 23, 24, 25,
- 26, 27, 23, 24, 25, 26, 27, 0, 9
-};
-/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/lib/bison.simple"
-/* This file comes from bison-1.28. */
-
-/* Skeleton output parser for bison,
- Copyright (C) 1984, 1989, 1990 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 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, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-/* This is the parser code that is written into each bison parser
- when the %semantic_parser declaration is not specified in the grammar.
- It was written by Richard Stallman by simplifying the hairy parser
- used when %semantic_parser is specified. */
-
-#ifndef YYSTACK_USE_ALLOCA
-#ifdef alloca
-#define YYSTACK_USE_ALLOCA
-#else /* alloca not defined */
-#ifdef __GNUC__
-#define YYSTACK_USE_ALLOCA
-#define alloca __builtin_alloca
-#else /* not GNU C. */
-#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
-#define YYSTACK_USE_ALLOCA
-#include <alloca.h>
-#else /* not sparc */
-/* We think this test detects Watcom and Microsoft C. */
-/* This used to test MSDOS, but that is a bad idea
- since that symbol is in the user namespace. */
-#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
-#if 0 /* No need for malloc.h, which pollutes the namespace;
- instead, just don't use alloca. */
-#include <malloc.h>
-#endif
-#else /* not MSDOS, or __TURBOC__ */
-#if defined(_AIX)
-/* I don't know what this was needed for, but it pollutes the namespace.
- So I turned it off. rms, 2 May 1997. */
-/* #include <malloc.h> */
- #pragma alloca
-#define YYSTACK_USE_ALLOCA
-#else /* not MSDOS, or __TURBOC__, or _AIX */
-#if 0
-#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
- and on HPUX 10. Eventually we can turn this on. */
-#define YYSTACK_USE_ALLOCA
-#define alloca __builtin_alloca
-#endif /* __hpux */
-#endif
-#endif /* not _AIX */
-#endif /* not MSDOS, or __TURBOC__ */
-#endif /* not sparc */
-#endif /* not GNU C */
-#endif /* alloca not defined */
-#endif /* YYSTACK_USE_ALLOCA not defined */
-
-#ifdef YYSTACK_USE_ALLOCA
-#define YYSTACK_ALLOC alloca
-#else
-#define YYSTACK_ALLOC malloc
-#endif
-
-/* Note: there must be only one dollar sign in this file.
- It is replaced by the list of actions, each action
- as one case of the switch. */
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY -2
-#define YYEOF 0
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
-#define YYERROR goto yyerrlab1
-/* Like YYERROR except do call yyerror.
- This remains here temporarily to ease the
- transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-#define YYFAIL goto yyerrlab
-#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(token, value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { yychar = (token), yylval = (value); \
- yychar1 = YYTRANSLATE (yychar); \
- YYPOPSTACK; \
- goto yybackup; \
- } \
- else \
- { yyerror ("syntax error: cannot back up"); YYERROR; } \
-while (0)
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-#ifndef YYPURE
-#define YYLEX yylex()
-#endif
-
-#ifdef YYPURE
-#ifdef YYLSP_NEEDED
-#ifdef YYLEX_PARAM
-#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
-#else
-#define YYLEX yylex(&yylval, &yylloc)
-#endif
-#else /* not YYLSP_NEEDED */
-#ifdef YYLEX_PARAM
-#define YYLEX yylex(&yylval, YYLEX_PARAM)
-#else
-#define YYLEX yylex(&yylval)
-#endif
-#endif /* not YYLSP_NEEDED */
-#endif
-
-/* If nonreentrant, generate the variables here */
-
-#ifndef YYPURE
-
-int yychar; /* the lookahead symbol */
-YYSTYPE yylval; /* the semantic value of the */
- /* lookahead symbol */
-
-#ifdef YYLSP_NEEDED
-YYLTYPE yylloc; /* location data for the lookahead */
- /* symbol */
-#endif
-
-int yynerrs; /* number of parse errors so far */
-#endif /* not YYPURE */
-
-#if YYDEBUG != 0
-int yydebug; /* nonzero means print parse trace */
-/* Since this is uninitialized, it does not stop multiple parsers
- from coexisting. */
-#endif
-
-/* YYINITDEPTH indicates the initial size of the parser's stacks */
-
-#ifndef YYINITDEPTH
-#define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH is the maximum size the stacks can grow to
- (effective only if the built-in stack extension method is used). */
-
-#if YYMAXDEPTH == 0
-#undef YYMAXDEPTH
-#endif
-
-#ifndef YYMAXDEPTH
-#define YYMAXDEPTH 10000
-#endif
-
-/* Define __yy_memcpy. Note that the size argument
- should be passed with type unsigned int, because that is what the non-GCC
- definitions require. With GCC, __builtin_memcpy takes an arg
- of type size_t, but it can handle unsigned int. */
-
-#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
-#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
-#else /* not GNU C or C++ */
-#ifndef __cplusplus
-
-/* This is the most reliable way to avoid incompatibilities
- in available built-in functions on various systems. */
-static void
-__yy_memcpy (to, from, count)
- char *to;
- char *from;
- unsigned int count;
-{
- register char *f = from;
- register char *t = to;
- register int i = count;
-
- while (i-- > 0)
- *t++ = *f++;
-}
-
-#else /* __cplusplus */
-
-/* This is the most reliable way to avoid incompatibilities
- in available built-in functions on various systems. */
-static void
-__yy_memcpy (char *to, char *from, unsigned int count)
-{
- register char *t = to;
- register char *f = from;
- register int i = count;
-
- while (i-- > 0)
- *t++ = *f++;
-}
-
-#endif
-#endif
-
-#line 217 "/usr/lib/bison.simple"
-
-/* The user can define YYPARSE_PARAM as the name of an argument to be passed
- into yyparse. The argument should have type void *.
- It should actually point to an object.
- Grammar actions can access the variable by casting it
- to the proper pointer type. */
-
-#ifdef YYPARSE_PARAM
-#ifdef __cplusplus
-#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL
-#else /* not __cplusplus */
-#define YYPARSE_PARAM_ARG YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
-#endif /* not __cplusplus */
-#else /* not YYPARSE_PARAM */
-#define YYPARSE_PARAM_ARG
-#define YYPARSE_PARAM_DECL
-#endif /* not YYPARSE_PARAM */
-
-/* Prevent warning if -Wstrict-prototypes. */
-#ifdef __GNUC__
-#ifdef YYPARSE_PARAM
-int yyparse (void *);
-#else
-int yyparse (void);
-#endif
-#endif
-
-int
-yyparse(YYPARSE_PARAM_ARG)
- YYPARSE_PARAM_DECL
-{
- register int yystate;
- register int yyn;
- register short *yyssp;
- register YYSTYPE *yyvsp;
- int yyerrstatus; /* number of tokens to shift before error messages enabled */
- int yychar1 = 0; /* lookahead token as an internal (translated) token number */
-
- short yyssa[YYINITDEPTH]; /* the state stack */
- YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
-
- short *yyss = yyssa; /* refer to the stacks thru separate pointers */
- YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
-
-#ifdef YYLSP_NEEDED
- YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
- YYLTYPE *yyls = yylsa;
- YYLTYPE *yylsp;
-
-#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
-#else
-#define YYPOPSTACK (yyvsp--, yyssp--)
-#endif
-
- int yystacksize = YYINITDEPTH;
- int yyfree_stacks = 0;
-
-#ifdef YYPURE
- int yychar;
- YYSTYPE yylval;
- int yynerrs;
-#ifdef YYLSP_NEEDED
- YYLTYPE yylloc;
-#endif
-#endif
-
- YYSTYPE yyval; /* the variable used to return */
- /* semantic values from the action */
- /* routines */
-
- int yylen;
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Starting parse\n");
-#endif
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
-
- yyssp = yyss - 1;
- yyvsp = yyvs;
-#ifdef YYLSP_NEEDED
- yylsp = yyls;
-#endif
-
-/* Push a new state, which is found in yystate . */
-/* In all cases, when you get here, the value and location stacks
- have just been pushed. so pushing a state here evens the stacks. */
-yynewstate:
-
- *++yyssp = yystate;
-
- if (yyssp >= yyss + yystacksize - 1)
- {
- /* Give user a chance to reallocate the stack */
- /* Use copies of these so that the &'s don't force the real ones into memory. */
- YYSTYPE *yyvs1 = yyvs;
- short *yyss1 = yyss;
-#ifdef YYLSP_NEEDED
- YYLTYPE *yyls1 = yyls;
-#endif
-
- /* Get the current used size of the three stacks, in elements. */
- int size = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- /* Each stack pointer address is followed by the size of
- the data in use in that stack, in bytes. */
-#ifdef YYLSP_NEEDED
- /* This used to be a conditional around just the two extra args,
- but that might be undefined if yyoverflow is a macro. */
- yyoverflow("parser stack overflow",
- &yyss1, size * sizeof (*yyssp),
- &yyvs1, size * sizeof (*yyvsp),
- &yyls1, size * sizeof (*yylsp),
- &yystacksize);
-#else
- yyoverflow("parser stack overflow",
- &yyss1, size * sizeof (*yyssp),
- &yyvs1, size * sizeof (*yyvsp),
- &yystacksize);
-#endif
-
- yyss = yyss1; yyvs = yyvs1;
-#ifdef YYLSP_NEEDED
- yyls = yyls1;
-#endif
-#else /* no yyoverflow */
- /* Extend the stack our own way. */
- if (yystacksize >= YYMAXDEPTH)
- {
- yyerror("parser stack overflow");
- if (yyfree_stacks)
- {
- free (yyss);
- free (yyvs);
-#ifdef YYLSP_NEEDED
- free (yyls);
-#endif
- }
- return 2;
- }
- yystacksize *= 2;
- if (yystacksize > YYMAXDEPTH)
- yystacksize = YYMAXDEPTH;
-#ifndef YYSTACK_USE_ALLOCA
- yyfree_stacks = 1;
-#endif
- yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
- __yy_memcpy ((char *)yyss, (char *)yyss1,
- size * (unsigned int) sizeof (*yyssp));
- yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
- __yy_memcpy ((char *)yyvs, (char *)yyvs1,
- size * (unsigned int) sizeof (*yyvsp));
-#ifdef YYLSP_NEEDED
- yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
- __yy_memcpy ((char *)yyls, (char *)yyls1,
- size * (unsigned int) sizeof (*yylsp));
-#endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + size - 1;
- yyvsp = yyvs + size - 1;
-#ifdef YYLSP_NEEDED
- yylsp = yyls + size - 1;
-#endif
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Stack size increased to %d\n", yystacksize);
-#endif
-
- if (yyssp >= yyss + yystacksize - 1)
- YYABORT;
- }
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Entering state %d\n", yystate);
-#endif
-
- goto yybackup;
- yybackup:
-
-/* Do appropriate processing given the current state. */
-/* Read a lookahead token if we need one and don't already have one. */
-/* yyresume: */
-
- /* First try to decide what to do without reference to lookahead token. */
-
- yyn = yypact[yystate];
- if (yyn == YYFLAG)
- goto yydefault;
-
- /* Not known => get a lookahead token if don't already have one. */
-
- /* yychar is either YYEMPTY or YYEOF
- or a valid token in external form. */
-
- if (yychar == YYEMPTY)
- {
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Reading a token: ");
-#endif
- yychar = YYLEX;
- }
-
- /* Convert token to internal form (in yychar1) for indexing tables with */
-
- if (yychar <= 0) /* This means end of input. */
- {
- yychar1 = 0;
- yychar = YYEOF; /* Don't call YYLEX any more */
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Now at end of input.\n");
-#endif
- }
- else
- {
- yychar1 = YYTRANSLATE(yychar);
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
- /* Give the individual parser a way to print the precise meaning
- of a token, for further debugging info. */
-#ifdef YYPRINT
- YYPRINT (stderr, yychar, yylval);
-#endif
- fprintf (stderr, ")\n");
- }
-#endif
- }
-
- yyn += yychar1;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
- goto yydefault;
-
- yyn = yytable[yyn];
-
- /* yyn is what to do for this token type in this state.
- Negative => reduce, -yyn is rule number.
- Positive => shift, yyn is new state.
- New state is final state => don't bother to shift,
- just return success.
- 0, or most negative number => error. */
-
- if (yyn < 0)
- {
- if (yyn == YYFLAG)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
- else if (yyn == 0)
- goto yyerrlab;
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- /* Shift the lookahead token. */
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
-#endif
-
- /* Discard the token being shifted unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
-
- *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
-
- /* count tokens shifted since error; after three, turn off error status. */
- if (yyerrstatus) yyerrstatus--;
-
- yystate = yyn;
- goto yynewstate;
-
-/* Do the default action for the current state. */
-yydefault:
-
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
-
-/* Do a reduction. yyn is the number of a rule to reduce with. */
-yyreduce:
- yylen = yyr2[yyn];
- if (yylen > 0)
- yyval = yyvsp[1-yylen]; /* implement default value of the action */
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- int i;
-
- fprintf (stderr, "Reducing via rule %d (line %d), ",
- yyn, yyrline[yyn]);
-
- /* Print the symbols being reduced, and their result. */
- for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
- fprintf (stderr, "%s ", yytname[yyrhs[i]]);
- fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
- }
-#endif
-
-
- switch (yyn) {
-
-case 1:
-#line 186 "cexp.y"
-{
- expression_value = yyvsp[0].integer.value;
-#ifdef TEST_EXP_READER
- expression_signedp = yyvsp[0].integer.signedp;
-#endif
- ;
- break;}
-case 3:
-#line 197 "cexp.y"
-{ if (pedantic)
- pedwarn ("comma operator in operand of `#if'");
- yyval.integer = yyvsp[0].integer; ;
- break;}
-case 4:
-#line 204 "cexp.y"
-{ yyval.integer.value = - yyvsp[0].integer.value;
- yyval.integer.signedp = yyvsp[0].integer.signedp;
- if ((yyval.integer.value & yyvsp[0].integer.value & yyval.integer.signedp) < 0)
- integer_overflow (); ;
- break;}
-case 5:
-#line 209 "cexp.y"
-{ yyval.integer.value = ! yyvsp[0].integer.value;
- yyval.integer.signedp = SIGNED; ;
- break;}
-case 6:
-#line 212 "cexp.y"
-{ yyval.integer = yyvsp[0].integer; ;
- break;}
-case 7:
-#line 214 "cexp.y"
-{ yyval.integer.value = ~ yyvsp[0].integer.value;
- yyval.integer.signedp = yyvsp[0].integer.signedp; ;
- break;}
-case 8:
-#line 217 "cexp.y"
-{ yyval.integer.value = check_assertion (yyvsp[0].name.address, yyvsp[0].name.length,
- 0, NULL_PTR);
- yyval.integer.signedp = SIGNED; ;
- break;}
-case 9:
-#line 221 "cexp.y"
-{ keyword_parsing = 1; ;
- break;}
-case 10:
-#line 223 "cexp.y"
-{ yyval.integer.value = check_assertion (yyvsp[-4].name.address, yyvsp[-4].name.length,
- 1, yyvsp[-1].keywords);
- keyword_parsing = 0;
- yyval.integer.signedp = SIGNED; ;
- break;}
-case 11:
-#line 228 "cexp.y"
-{ yyval.integer = yyvsp[-1].integer; ;
- break;}
-case 12:
-#line 233 "cexp.y"
-{ yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp;
- if (yyval.integer.signedp)
- {
- yyval.integer.value = yyvsp[-2].integer.value * yyvsp[0].integer.value;
- if (yyvsp[-2].integer.value
- && (yyval.integer.value / yyvsp[-2].integer.value != yyvsp[0].integer.value
- || (yyval.integer.value & yyvsp[-2].integer.value & yyvsp[0].integer.value) < 0))
- integer_overflow ();
- }
- else
- yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
- * yyvsp[0].integer.value); ;
- break;}
-case 13:
-#line 246 "cexp.y"
-{ if (yyvsp[0].integer.value == 0)
- {
- if (!skip_evaluation)
- error ("division by zero in #if");
- yyvsp[0].integer.value = 1;
- }
- yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp;
- if (yyval.integer.signedp)
- {
- yyval.integer.value = yyvsp[-2].integer.value / yyvsp[0].integer.value;
- if ((yyval.integer.value & yyvsp[-2].integer.value & yyvsp[0].integer.value) < 0)
- integer_overflow ();
- }
- else
- yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
- / yyvsp[0].integer.value); ;
- break;}
-case 14:
-#line 263 "cexp.y"
-{ if (yyvsp[0].integer.value == 0)
- {
- if (!skip_evaluation)
- error ("division by zero in #if");
- yyvsp[0].integer.value = 1;
- }
- yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp;
- if (yyval.integer.signedp)
- yyval.integer.value = yyvsp[-2].integer.value % yyvsp[0].integer.value;
- else
- yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
- % yyvsp[0].integer.value); ;
- break;}
-case 15:
-#line 276 "cexp.y"
-{ yyval.integer.value = yyvsp[-2].integer.value + yyvsp[0].integer.value;
- yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp;
- if (overflow_sum_sign (yyvsp[-2].integer.value, yyvsp[0].integer.value,
- yyval.integer.value, yyval.integer.signedp))
- integer_overflow (); ;
- break;}
-case 16:
-#line 282 "cexp.y"
-{ yyval.integer.value = yyvsp[-2].integer.value - yyvsp[0].integer.value;
- yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp;
- if (overflow_sum_sign (yyval.integer.value, yyvsp[0].integer.value,
- yyvsp[-2].integer.value, yyval.integer.signedp))
- integer_overflow (); ;
- break;}
-case 17:
-#line 288 "cexp.y"
-{ yyval.integer.signedp = yyvsp[-2].integer.signedp;
- if ((yyvsp[0].integer.value & yyvsp[0].integer.signedp) < 0)
- yyval.integer.value = right_shift (&yyvsp[-2].integer, -yyvsp[0].integer.value);
- else
- yyval.integer.value = left_shift (&yyvsp[-2].integer, yyvsp[0].integer.value); ;
- break;}
-case 18:
-#line 294 "cexp.y"
-{ yyval.integer.signedp = yyvsp[-2].integer.signedp;
- if ((yyvsp[0].integer.value & yyvsp[0].integer.signedp) < 0)
- yyval.integer.value = left_shift (&yyvsp[-2].integer, -yyvsp[0].integer.value);
- else
- yyval.integer.value = right_shift (&yyvsp[-2].integer, yyvsp[0].integer.value); ;
- break;}
-case 19:
-#line 300 "cexp.y"
-{ yyval.integer.value = (yyvsp[-2].integer.value == yyvsp[0].integer.value);
- yyval.integer.signedp = SIGNED; ;
- break;}
-case 20:
-#line 303 "cexp.y"
-{ yyval.integer.value = (yyvsp[-2].integer.value != yyvsp[0].integer.value);
- yyval.integer.signedp = SIGNED; ;
- break;}
-case 21:
-#line 306 "cexp.y"
-{ yyval.integer.signedp = SIGNED;
- if (yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp)
- yyval.integer.value = yyvsp[-2].integer.value <= yyvsp[0].integer.value;
- else
- yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
- <= yyvsp[0].integer.value); ;
- break;}
-case 22:
-#line 313 "cexp.y"
-{ yyval.integer.signedp = SIGNED;
- if (yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp)
- yyval.integer.value = yyvsp[-2].integer.value >= yyvsp[0].integer.value;
- else
- yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
- >= yyvsp[0].integer.value); ;
- break;}
-case 23:
-#line 320 "cexp.y"
-{ yyval.integer.signedp = SIGNED;
- if (yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp)
- yyval.integer.value = yyvsp[-2].integer.value < yyvsp[0].integer.value;
- else
- yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
- < yyvsp[0].integer.value); ;
- break;}
-case 24:
-#line 327 "cexp.y"
-{ yyval.integer.signedp = SIGNED;
- if (yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp)
- yyval.integer.value = yyvsp[-2].integer.value > yyvsp[0].integer.value;
- else
- yyval.integer.value = ((unsigned HOST_WIDEST_INT) yyvsp[-2].integer.value
- > yyvsp[0].integer.value); ;
- break;}
-case 25:
-#line 334 "cexp.y"
-{ yyval.integer.value = yyvsp[-2].integer.value & yyvsp[0].integer.value;
- yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp; ;
- break;}
-case 26:
-#line 337 "cexp.y"
-{ yyval.integer.value = yyvsp[-2].integer.value ^ yyvsp[0].integer.value;
- yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp; ;
- break;}
-case 27:
-#line 340 "cexp.y"
-{ yyval.integer.value = yyvsp[-2].integer.value | yyvsp[0].integer.value;
- yyval.integer.signedp = yyvsp[-2].integer.signedp & yyvsp[0].integer.signedp; ;
- break;}
-case 28:
-#line 343 "cexp.y"
-{ skip_evaluation += !yyvsp[-1].integer.value; ;
- break;}
-case 29:
-#line 345 "cexp.y"
-{ skip_evaluation -= !yyvsp[-3].integer.value;
- yyval.integer.value = (yyvsp[-3].integer.value && yyvsp[0].integer.value);
- yyval.integer.signedp = SIGNED; ;
- break;}
-case 30:
-#line 349 "cexp.y"
-{ skip_evaluation += !!yyvsp[-1].integer.value; ;
- break;}
-case 31:
-#line 351 "cexp.y"
-{ skip_evaluation -= !!yyvsp[-3].integer.value;
- yyval.integer.value = (yyvsp[-3].integer.value || yyvsp[0].integer.value);
- yyval.integer.signedp = SIGNED; ;
- break;}
-case 32:
-#line 355 "cexp.y"
-{ skip_evaluation += !yyvsp[-1].integer.value; ;
- break;}
-case 33:
-#line 357 "cexp.y"
-{ skip_evaluation += !!yyvsp[-4].integer.value - !yyvsp[-4].integer.value; ;
- break;}
-case 34:
-#line 359 "cexp.y"
-{ skip_evaluation -= !!yyvsp[-6].integer.value;
- yyval.integer.value = yyvsp[-6].integer.value ? yyvsp[-3].integer.value : yyvsp[0].integer.value;
- yyval.integer.signedp = yyvsp[-3].integer.signedp & yyvsp[0].integer.signedp; ;
- break;}
-case 35:
-#line 363 "cexp.y"
-{ yyval.integer = yylval.integer; ;
- break;}
-case 36:
-#line 365 "cexp.y"
-{ yyval.integer = yylval.integer; ;
- break;}
-case 37:
-#line 367 "cexp.y"
-{ if (warn_undef && !skip_evaluation)
- warning ("`%.*s' is not defined",
- yyvsp[0].name.length, yyvsp[0].name.address);
- yyval.integer.value = 0;
- yyval.integer.signedp = SIGNED; ;
- break;}
-case 38:
-#line 375 "cexp.y"
-{ yyval.keywords = 0; ;
- break;}
-case 39:
-#line 377 "cexp.y"
-{ struct arglist *temp;
- yyval.keywords = (struct arglist *) xmalloc (sizeof (struct arglist));
- yyval.keywords->next = yyvsp[-2].keywords;
- yyval.keywords->name = (U_CHAR *) "(";
- yyval.keywords->length = 1;
- temp = yyval.keywords;
- while (temp != 0 && temp->next != 0)
- temp = temp->next;
- temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
- temp->next->next = yyvsp[0].keywords;
- temp->next->name = (U_CHAR *) ")";
- temp->next->length = 1; ;
- break;}
-case 40:
-#line 390 "cexp.y"
-{ yyval.keywords = (struct arglist *) xmalloc (sizeof (struct arglist));
- yyval.keywords->name = yyvsp[-1].name.address;
- yyval.keywords->length = yyvsp[-1].name.length;
- yyval.keywords->next = yyvsp[0].keywords; ;
- break;}
-}
- /* the action file gets copied in in place of this dollarsign */
-#line 543 "/usr/lib/bison.simple"
-
- yyvsp -= yylen;
- yyssp -= yylen;
-#ifdef YYLSP_NEEDED
- yylsp -= yylen;
-#endif
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- short *ssp1 = yyss - 1;
- fprintf (stderr, "state stack now");
- while (ssp1 != yyssp)
- fprintf (stderr, " %d", *++ssp1);
- fprintf (stderr, "\n");
- }
-#endif
-
- *++yyvsp = yyval;
-
-#ifdef YYLSP_NEEDED
- yylsp++;
- if (yylen == 0)
- {
- yylsp->first_line = yylloc.first_line;
- yylsp->first_column = yylloc.first_column;
- yylsp->last_line = (yylsp-1)->last_line;
- yylsp->last_column = (yylsp-1)->last_column;
- yylsp->text = 0;
- }
- else
- {
- yylsp->last_line = (yylsp+yylen-1)->last_line;
- yylsp->last_column = (yylsp+yylen-1)->last_column;
- }
-#endif
-
- /* Now "shift" the result of the reduction.
- Determine what state that goes to,
- based on the state we popped back to
- and the rule number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
- if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTBASE];
-
- goto yynewstate;
-
-yyerrlab: /* here on detecting error */
-
- if (! yyerrstatus)
- /* If not already recovering from an error, report this error. */
- {
- ++yynerrs;
-
-#ifdef YYERROR_VERBOSE
- yyn = yypact[yystate];
-
- if (yyn > YYFLAG && yyn < YYLAST)
- {
- int size = 0;
- char *msg;
- int x, count;
-
- count = 0;
- /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
- for (x = (yyn < 0 ? -yyn : 0);
- x < (sizeof(yytname) / sizeof(char *)); x++)
- if (yycheck[x + yyn] == x)
- size += strlen(yytname[x]) + 15, count++;
- msg = (char *) malloc(size + 15);
- if (msg != 0)
- {
- strcpy(msg, "parse error");
-
- if (count < 5)
- {
- count = 0;
- for (x = (yyn < 0 ? -yyn : 0);
- x < (sizeof(yytname) / sizeof(char *)); x++)
- if (yycheck[x + yyn] == x)
- {
- strcat(msg, count == 0 ? ", expecting `" : " or `");
- strcat(msg, yytname[x]);
- strcat(msg, "'");
- count++;
- }
- }
- yyerror(msg);
- free(msg);
- }
- else
- yyerror ("parse error; also virtual memory exceeded");
- }
- else
-#endif /* YYERROR_VERBOSE */
- yyerror("parse error");
- }
-
- goto yyerrlab1;
-yyerrlab1: /* here on error raised explicitly by an action */
-
- if (yyerrstatus == 3)
- {
- /* if just tried and failed to reuse lookahead token after an error, discard it. */
-
- /* return failure if at end of input */
- if (yychar == YYEOF)
- YYABORT;
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
-#endif
-
- yychar = YYEMPTY;
- }
-
- /* Else will try to reuse lookahead token
- after shifting the error token. */
-
- yyerrstatus = 3; /* Each real token shifted decrements this */
-
- goto yyerrhandle;
-
-yyerrdefault: /* current state does not do anything special for the error token. */
-
-#if 0
- /* This is wrong; only states that explicitly want error tokens
- should shift them. */
- yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
- if (yyn) goto yydefault;
-#endif
-
-yyerrpop: /* pop the current state because it cannot handle the error token */
-
- if (yyssp == yyss) YYABORT;
- yyvsp--;
- yystate = *--yyssp;
-#ifdef YYLSP_NEEDED
- yylsp--;
-#endif
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- short *ssp1 = yyss - 1;
- fprintf (stderr, "Error: state stack now");
- while (ssp1 != yyssp)
- fprintf (stderr, " %d", *++ssp1);
- fprintf (stderr, "\n");
- }
-#endif
-
-yyerrhandle:
-
- yyn = yypact[yystate];
- if (yyn == YYFLAG)
- goto yyerrdefault;
-
- yyn += YYTERROR;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
- goto yyerrdefault;
-
- yyn = yytable[yyn];
- if (yyn < 0)
- {
- if (yyn == YYFLAG)
- goto yyerrpop;
- yyn = -yyn;
- goto yyreduce;
- }
- else if (yyn == 0)
- goto yyerrpop;
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Shifting error token, ");
-#endif
-
- *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
-
- yystate = yyn;
- goto yynewstate;
-
- yyacceptlab:
- /* YYACCEPT comes here. */
- if (yyfree_stacks)
- {
- free (yyss);
- free (yyvs);
-#ifdef YYLSP_NEEDED
- free (yyls);
-#endif
- }
- return 0;
-
- yyabortlab:
- /* YYABORT comes here. */
- if (yyfree_stacks)
- {
- free (yyss);
- free (yyvs);
-#ifdef YYLSP_NEEDED
- free (yyls);
-#endif
- }
- return 1;
-}
-#line 395 "cexp.y"
-
-
-/* During parsing of a C expression, the pointer to the next character
- is in this variable. */
-
-static char *lexptr;
-
-/* Take care of parsing a number (anything that starts with a digit).
- Set yylval and return the token type; update lexptr.
- LEN is the number of characters in it. */
-
-/* maybe needs to actually deal with floating point numbers */
-
-static int
-parse_number (olen)
- int olen;
-{
- register char *p = lexptr;
- register int c;
- register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
- register int base = 10;
- register int len = olen;
- register int overflow = 0;
- register int digit, largest_digit = 0;
- int spec_long = 0;
-
- yylval.integer.signedp = SIGNED;
-
- if (*p == '0') {
- base = 8;
- if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
- p += 2;
- base = 16;
- len -= 2;
- }
- }
-
- max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
-
- for (; len > 0; len--) {
- c = *p++;
-
- if (c >= '0' && c <= '9')
- digit = c - '0';
- else if (base == 16 && c >= 'a' && c <= 'f')
- digit = c - 'a' + 10;
- else if (base == 16 && c >= 'A' && c <= 'F')
- digit = c - 'A' + 10;
- else {
- /* `l' means long, and `u' means unsigned. */
- while (1) {
- if (c == 'l' || c == 'L')
- {
- if (!pedantic < spec_long)
- yyerror ("too many `l's in integer constant");
- spec_long++;
- }
- else if (c == 'u' || c == 'U')
- {
- if (! yylval.integer.signedp)
- yyerror ("two `u's in integer constant");
- yylval.integer.signedp = UNSIGNED;
- }
- else {
- if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
- yyerror ("Floating point numbers not allowed in #if expressions");
- else
- yyerror ("missing white space after number `%.*s'",
- (int) (p - lexptr - 1), lexptr);
- }
-
- if (--len == 0)
- break;
- c = *p++;
- }
- /* Don't look for any more digits after the suffixes. */
- break;
- }
- if (largest_digit < digit)
- largest_digit = digit;
- nd = n * base + digit;
- overflow |= (max_over_base < n) | (nd < n);
- n = nd;
- }
-
- if (base <= largest_digit)
- pedwarn ("integer constant contains digits beyond the radix");
-
- if (overflow)
- pedwarn ("integer constant out of range");
-
- /* If too big to be signed, consider it unsigned. */
- if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
- {
- if (base == 10)
- warning ("integer constant is so large that it is unsigned");
- yylval.integer.signedp = UNSIGNED;
- }
-
- lexptr = p;
- yylval.integer.value = n;
- return INT;
-}
-
-struct token {
- const char *operator;
- int token;
-};
-
-static struct token tokentab2[] = {
- {"&&", AND},
- {"||", OR},
- {"<<", LSH},
- {">>", RSH},
- {"==", EQUAL},
- {"!=", NOTEQUAL},
- {"<=", LEQ},
- {">=", GEQ},
- {"++", ERROR},
- {"--", ERROR},
- {NULL, ERROR}
-};
-
-/* Read one token, getting characters through lexptr. */
-
-static int
-yylex ()
-{
- register int c;
- register int namelen;
- register unsigned char *tokstart;
- register struct token *toktab;
- int wide_flag;
- HOST_WIDEST_INT mask;
-
- retry:
-
- tokstart = (unsigned char *) lexptr;
- c = *tokstart;
- /* See if it is a special token of length 2. */
- if (! keyword_parsing)
- for (toktab = tokentab2; toktab->operator != NULL; toktab++)
- if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
- lexptr += 2;
- if (toktab->token == ERROR)
- yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
- return toktab->token;
- }
-
- switch (c) {
- case '\n':
- return 0;
-
- case ' ':
- case '\t':
- case '\r':
- lexptr++;
- goto retry;
-
- case 'L':
- /* Capital L may start a wide-string or wide-character constant. */
- if (lexptr[1] == '\'')
- {
- lexptr++;
- wide_flag = 1;
- mask = MAX_WCHAR_TYPE_MASK;
- goto char_constant;
- }
- if (lexptr[1] == '"')
- {
- lexptr++;
- wide_flag = 1;
- mask = MAX_WCHAR_TYPE_MASK;
- goto string_constant;
- }
- break;
-
- case '\'':
- wide_flag = 0;
- mask = MAX_CHAR_TYPE_MASK;
- char_constant:
- lexptr++;
- if (keyword_parsing) {
- char *start_ptr = lexptr - 1;
- while (1) {
- c = *lexptr++;
- if (c == '\\')
- c = parse_escape (&lexptr, mask);
- else if (c == '\'')
- break;
- }
- yylval.name.address = tokstart;
- yylval.name.length = lexptr - start_ptr;
- return NAME;
- }
-
- /* This code for reading a character constant
- handles multicharacter constants and wide characters.
- It is mostly copied from c-lex.c. */
- {
- register HOST_WIDEST_INT result = 0;
- register int num_chars = 0;
- int chars_seen = 0;
- unsigned width = MAX_CHAR_TYPE_SIZE;
- int max_chars;
-#ifdef MULTIBYTE_CHARS
- int longest_char = local_mb_cur_max ();
- char *token_buffer = (char *) alloca (longest_char);
- (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
-#endif
-
- max_chars = MAX_LONG_TYPE_SIZE / width;
- if (wide_flag)
- width = MAX_WCHAR_TYPE_SIZE;
-
- while (1)
- {
- c = *lexptr++;
-
- if (c == '\'' || c == EOF)
- break;
-
- ++chars_seen;
- if (c == '\\')
- {
- c = parse_escape (&lexptr, mask);
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- wchar_t wc;
- int i;
- int char_len = -1;
- for (i = 1; i <= longest_char; ++i)
- {
- token_buffer[i - 1] = c;
- char_len = local_mbtowc (& wc, token_buffer, i);
- if (char_len != -1)
- break;
- c = *lexptr++;
- }
- if (char_len > 1)
- {
- /* mbtowc sometimes needs an extra char before accepting */
- if (char_len < i)
- lexptr--;
- if (! wide_flag)
- {
- /* Merge character into result; ignore excess chars. */
- for (i = 1; i <= char_len; ++i)
- {
- if (i > max_chars)
- break;
- if (width < HOST_BITS_PER_INT)
- result = (result << width)
- | (token_buffer[i - 1]
- & ((1 << width) - 1));
- else
- result = token_buffer[i - 1];
- }
- num_chars += char_len;
- continue;
- }
- }
- else
- {
- if (char_len == -1)
- warning ("Ignoring invalid multibyte character");
- }
- if (wide_flag)
- c = wc;
-#endif /* ! MULTIBYTE_CHARS */
- }
-
- if (wide_flag)
- {
- if (chars_seen == 1) /* only keep the first one */
- result = c;
- continue;
- }
-
- /* Merge character into result; ignore excess chars. */
- num_chars++;
- if (num_chars <= max_chars)
- {
- if (width < HOST_BITS_PER_INT)
- result = (result << width) | (c & ((1 << width) - 1));
- else
- result = c;
- }
- }
-
- if (c != '\'')
- error ("malformatted character constant");
- else if (chars_seen == 0)
- error ("empty character constant");
- else if (num_chars > max_chars)
- {
- num_chars = max_chars;
- error ("character constant too long");
- }
- else if (chars_seen != 1 && ! traditional)
- warning ("multi-character character constant");
-
- /* If char type is signed, sign-extend the constant. */
- if (! wide_flag)
- {
- int num_bits = num_chars * width;
- if (num_bits == 0)
- /* We already got an error; avoid invalid shift. */
- yylval.integer.value = 0;
- else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
- sizeof ("__CHAR_UNSIGNED__") - 1, -1)
- || ((result >> (num_bits - 1)) & 1) == 0)
- yylval.integer.value
- = result & (~ (unsigned HOST_WIDEST_INT) 0
- >> (HOST_BITS_PER_WIDEST_INT - num_bits));
- else
- yylval.integer.value
- = result | ~(~ (unsigned HOST_WIDEST_INT) 0
- >> (HOST_BITS_PER_WIDEST_INT - num_bits));
- }
- else
- {
- yylval.integer.value = result;
- }
- }
-
- /* This is always a signed type. */
- yylval.integer.signedp = SIGNED;
-
- return CHAR;
-
- /* some of these chars are invalid in constant expressions;
- maybe do something about them later */
- case '/':
- case '+':
- case '-':
- case '*':
- case '%':
- case '|':
- case '&':
- case '^':
- case '~':
- case '!':
- case '@':
- case '<':
- case '>':
- case '[':
- case ']':
- case '.':
- case '?':
- case ':':
- case '=':
- case '{':
- case '}':
- case ',':
- case '#':
- if (keyword_parsing)
- break;
- case '(':
- case ')':
- lexptr++;
- return c;
-
- case '"':
- mask = MAX_CHAR_TYPE_MASK;
- string_constant:
- if (keyword_parsing) {
- char *start_ptr = lexptr;
- lexptr++;
- while (1) {
- c = *lexptr++;
- if (c == '\\')
- c = parse_escape (&lexptr, mask);
- else if (c == '"')
- break;
- }
- yylval.name.address = tokstart;
- yylval.name.length = lexptr - start_ptr;
- return NAME;
- }
- yyerror ("string constants not allowed in #if expressions");
- return ERROR;
- }
-
- if (c >= '0' && c <= '9' && !keyword_parsing) {
- /* It's a number */
- for (namelen = 1; ; namelen++) {
- int d = tokstart[namelen];
- if (! ((is_idchar[d] || d == '.')
- || ((d == '-' || d == '+')
- && (c == 'e' || c == 'E'
- || ((c == 'p' || c == 'P') && ! c89))
- && ! traditional)))
- break;
- c = d;
- }
- return parse_number (namelen);
- }
-
- /* It is a name. See how long it is. */
-
- if (keyword_parsing) {
- for (namelen = 0;; namelen++) {
- if (is_space[tokstart[namelen]])
- break;
- if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
- break;
- if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
- break;
- }
- } else {
- if (!is_idstart[c]) {
- yyerror ("Invalid token in expression");
- return ERROR;
- }
-
- for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
- ;
- }
-
- lexptr += namelen;
- yylval.name.address = tokstart;
- yylval.name.length = namelen;
- return NAME;
-}
-
-
-/* Parse a C escape sequence. STRING_PTR points to a variable
- containing a pointer to the string to parse. That pointer
- is updated past the characters we use. The value of the
- escape sequence is returned.
-
- RESULT_MASK is used to mask out the result;
- an error is reported if bits are lost thereby.
-
- A negative value means the sequence \ newline was seen,
- which is supposed to be equivalent to nothing at all.
-
- If \ is followed by a null character, we return a negative
- value and leave the string pointer pointing at the null character.
-
- If \ is followed by 000, we return 0 and leave the string pointer
- after the zeros. A value of 0 does not mean end of string. */
-
-HOST_WIDEST_INT
-parse_escape (string_ptr, result_mask)
- char **string_ptr;
- HOST_WIDEST_INT result_mask;
-{
- register int c = *(*string_ptr)++;
- switch (c)
- {
- case 'a':
- return TARGET_BELL;
- case 'b':
- return TARGET_BS;
- case 'e':
- case 'E':
- if (pedantic)
- pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
- return TARGET_ESC;
- case 'f':
- return TARGET_FF;
- case 'n':
- return TARGET_NEWLINE;
- case 'r':
- return TARGET_CR;
- case 't':
- return TARGET_TAB;
- case 'v':
- return TARGET_VT;
- case '\n':
- return -2;
- case 0:
- (*string_ptr)--;
- return 0;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- {
- register HOST_WIDEST_INT i = c - '0';
- register int count = 0;
- while (++count < 3)
- {
- c = *(*string_ptr)++;
- if (c >= '0' && c <= '7')
- i = (i << 3) + c - '0';
- else
- {
- (*string_ptr)--;
- break;
- }
- }
- if (i != (i & result_mask))
- {
- i &= result_mask;
- pedwarn ("octal escape sequence out of range");
- }
- return i;
- }
- case 'x':
- {
- register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
- register int digits_found = 0, digit;
- for (;;)
- {
- c = *(*string_ptr)++;
- if (c >= '0' && c <= '9')
- digit = c - '0';
- else if (c >= 'a' && c <= 'f')
- digit = c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
- digit = c - 'A' + 10;
- else
- {
- (*string_ptr)--;
- break;
- }
- overflow |= i ^ (i << 4 >> 4);
- i = (i << 4) + digit;
- digits_found = 1;
- }
- if (!digits_found)
- yyerror ("\\x used with no following hex digits");
- if (overflow | (i != (i & result_mask)))
- {
- i &= result_mask;
- pedwarn ("hex escape sequence out of range");
- }
- return i;
- }
- default:
- return c;
- }
-}
-
-static void
-integer_overflow ()
-{
- if (!skip_evaluation && pedantic)
- pedwarn ("integer overflow in preprocessor expression");
-}
-
-static HOST_WIDEST_INT
-left_shift (a, b)
- struct constant *a;
- unsigned HOST_WIDEST_INT b;
-{
- /* It's unclear from the C standard whether shifts can overflow.
- The following code ignores overflow; perhaps a C standard
- interpretation ruling is needed. */
- if (b >= HOST_BITS_PER_WIDEST_INT)
- return 0;
- else
- return (unsigned HOST_WIDEST_INT) a->value << b;
-}
-
-static HOST_WIDEST_INT
-right_shift (a, b)
- struct constant *a;
- unsigned HOST_WIDEST_INT b;
-{
- if (b >= HOST_BITS_PER_WIDEST_INT)
- return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0;
- else if (a->signedp)
- return a->value >> b;
- else
- return (unsigned HOST_WIDEST_INT) a->value >> b;
-}
-
-/* This page contains the entry point to this file. */
-
-/* Parse STRING as an expression, and complain if this fails
- to use up all of the contents of STRING.
- STRING may contain '\0' bytes; it is terminated by the first '\n'
- outside a string constant, so that we can diagnose '\0' properly.
- If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
- We do not support C comments. They should be removed before
- this function is called. */
-
-HOST_WIDEST_INT
-parse_c_expression (string, warn_undefined)
- char *string;
- int warn_undefined;
-{
- lexptr = string;
- warn_undef = warn_undefined;
-
- /* if there is some sort of scanning error, just return 0 and assume
- the parsing routine has printed an error message somewhere.
- there is surely a better thing to do than this. */
- if (setjmp (parse_return_error))
- return 0;
-
- if (yyparse () != 0)
- abort ();
-
- if (*lexptr != '\n')
- error ("Junk after end of expression.");
-
- return expression_value; /* set by yyparse () */
-}
-
-static void
-yyerror VPARAMS ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- verror (msgid, args);
- va_end (args);
- skip_evaluation = 0;
- longjmp (parse_return_error, 1);
-}
-
-
-#ifdef TEST_EXP_READER
-
-#if YYDEBUG
-extern int yydebug;
-#endif
-
-int pedantic;
-int traditional;
-int c89;
-
-int main PARAMS ((int, char **));
-static void initialize_random_junk PARAMS ((void));
-static void print_unsigned_host_widest_int PARAMS ((unsigned HOST_WIDEST_INT));
-
-/* Main program for testing purposes. */
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int n, c;
- char buf[1024];
- unsigned HOST_WIDEST_INT u;
-
- pedantic = 1 < argc;
- traditional = 2 < argc;
- c89 = 3 < argc;
-#if YYDEBUG
- yydebug = 4 < argc;
-#endif
- initialize_random_junk ();
-
- for (;;) {
- printf ("enter expression: ");
- n = 0;
- while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
- n++;
- if (c == EOF)
- break;
- parse_c_expression (buf, 1);
- printf ("parser returned ");
- u = (unsigned HOST_WIDEST_INT) expression_value;
- if (expression_value < 0 && expression_signedp) {
- u = -u;
- printf ("-");
- }
- if (u == 0)
- printf ("0");
- else
- print_unsigned_host_widest_int (u);
- if (! expression_signedp)
- printf("u");
- printf ("\n");
- }
-
- return 0;
-}
-
-static void
-print_unsigned_host_widest_int (u)
- unsigned HOST_WIDEST_INT u;
-{
- if (u) {
- print_unsigned_host_widest_int (u / 10);
- putchar ('0' + (int) (u % 10));
- }
-}
-
-/* table to tell if char can be part of a C identifier. */
-unsigned char is_idchar[256];
-/* table to tell if char can be first char of a c identifier. */
-unsigned char is_idstart[256];
-/* table to tell if c is horizontal or vertical space. */
-unsigned char is_space[256];
-
-/*
- * initialize random junk in the hash table and maybe other places
- */
-static void
-initialize_random_junk ()
-{
- register int i;
-
- /*
- * Set up is_idchar and is_idstart tables. These should be
- * faster than saying (is_alpha (c) || c == '_'), etc.
- * Must do set up these things before calling any routines tthat
- * refer to them.
- */
- for (i = 'a'; i <= 'z'; i++) {
- ++is_idchar[TOUPPER(i)];
- ++is_idchar[i];
- ++is_idstart[TOUPPER(i)];
- ++is_idstart[i];
- }
- for (i = '0'; i <= '9'; i++)
- ++is_idchar[i];
- ++is_idchar['_'];
- ++is_idstart['_'];
- ++is_idchar['$'];
- ++is_idstart['$'];
-
- ++is_space[' '];
- ++is_space['\t'];
- ++is_space['\v'];
- ++is_space['\f'];
- ++is_space['\n'];
- ++is_space['\r'];
-}
-
-void
-error VPARAMS ((char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, char *);
-#endif
-
- fprintf (stderr, "error: ");
- vfprintf (stderr, _(msgid), args);
- fprintf (stderr, "\n");
- va_end (args);
-}
-
-void
-pedwarn VPARAMS ((char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, char *);
-#endif
-
- fprintf (stderr, "pedwarn: ");
- vfprintf (stderr, _(msgid), args);
- fprintf (stderr, "\n");
- va_end (args);
-}
-
-void
-warning VPARAMS ((char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, char *);
-#endif
-
- fprintf (stderr, "warning: ");
- vfprintf (stderr, _(msgid), args);
- fprintf (stderr, "\n");
- va_end (args);
-}
-
-
-int
-check_assertion (name, sym_length, tokens_specified, tokens)
- U_CHAR *name;
- int sym_length;
- int tokens_specified;
- struct arglist *tokens;
-{
- return 0;
-}
-
-struct hashnode *
-lookup (name, len, hash)
- U_CHAR *name;
- int len;
- int hash;
-{
- return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
-}
-
-PTR
-xmalloc (size)
- size_t size;
-{
- return (PTR) malloc (size);
-}
-#endif
diff --git a/gcc/cexp.y b/gcc/cexp.y
deleted file mode 100644
index 1fb2f5d9f42..00000000000
--- a/gcc/cexp.y
+++ /dev/null
@@ -1,1223 +0,0 @@
-/* Parse C expressions for CCCP.
- Copyright (C) 1987, 1992, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation.
-
-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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
-
- Adapted from expread.y of GDB by Paul Rubin, July 1986. */
-
-/* Parse a C expression from text in a string */
-
-%{
-#include "config.h"
-
-#include "system.h"
-#include "intl.h"
-#include <setjmp.h>
-/* #define YYDEBUG 1 */
-
-#ifdef MULTIBYTE_CHARS
-#include "mbchar.h"
-#include <locale.h>
-#endif /* MULTIBYTE_CHARS */
-
-typedef unsigned char U_CHAR;
-
-/* This is used for communicating lists of keywords with cccp.c. */
-struct arglist {
- struct arglist *next;
- U_CHAR *name;
- int length;
- int argno;
-};
-
-HOST_WIDEST_INT parse_c_expression PARAMS ((char *, int));
-
-static int yylex PARAMS ((void));
-static void yyerror PARAMS ((const char *, ...))
- ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-static HOST_WIDEST_INT expression_value;
-#ifdef TEST_EXP_READER
-static int expression_signedp;
-#endif
-
-static jmp_buf parse_return_error;
-
-/* Nonzero means count most punctuation as part of a name. */
-static int keyword_parsing = 0;
-
-/* Nonzero means do not evaluate this expression.
- This is a count, since unevaluated expressions can nest. */
-static int skip_evaluation;
-
-/* Nonzero means warn if undefined identifiers are evaluated. */
-static int warn_undef;
-
-/* some external tables of character types */
-extern unsigned char is_idstart[], is_idchar[], is_space[];
-
-/* Flag for -pedantic. */
-extern int pedantic;
-
-/* Flag for -traditional. */
-extern int traditional;
-
-/* Flag for -lang-c89. */
-extern int c89;
-
-#ifndef CHAR_TYPE_SIZE
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-#endif
-
-#ifndef INT_TYPE_SIZE
-#define INT_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef LONG_TYPE_SIZE
-#define LONG_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef WCHAR_TYPE_SIZE
-#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
-#endif
-
-#ifndef MAX_CHAR_TYPE_SIZE
-#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
-#endif
-
-#ifndef MAX_INT_TYPE_SIZE
-#define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
-#endif
-
-#ifndef MAX_LONG_TYPE_SIZE
-#define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
-#endif
-
-#ifndef MAX_WCHAR_TYPE_SIZE
-#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
-#endif
-
-#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
- ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
- : ~ (HOST_WIDEST_INT) 0)
-
-#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
- ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
- : ~ (HOST_WIDEST_INT) 0)
-
-/* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
- Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
- Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
- Then this yields nonzero if overflow occurred during the addition.
- Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
- and SIGNEDP is negative.
- Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
-#define overflow_sum_sign(a, b, sum, signedp) \
- ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
-
-struct constant;
-
-HOST_WIDEST_INT parse_escape PARAMS ((char **, HOST_WIDEST_INT));
-int check_assertion PARAMS ((U_CHAR *, int, int, struct arglist *));
-struct hashnode *lookup PARAMS ((U_CHAR *, int, int));
-void error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void verror PARAMS ((const char *, va_list));
-void pedwarn PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-void warning PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-
-static int parse_number PARAMS ((int));
-static HOST_WIDEST_INT left_shift PARAMS ((struct constant *, unsigned HOST_WIDEST_INT));
-static HOST_WIDEST_INT right_shift PARAMS ((struct constant *, unsigned HOST_WIDEST_INT));
-static void integer_overflow PARAMS ((void));
-
-/* `signedp' values */
-#define SIGNED (~0)
-#define UNSIGNED 0
-%}
-
-%union {
- struct constant {HOST_WIDEST_INT value; int signedp;} integer;
- struct name {U_CHAR *address; int length;} name;
- struct arglist *keywords;
-}
-
-%type <integer> exp exp1 start
-%type <keywords> keywords
-%token <integer> INT CHAR
-%token <name> NAME
-%token <integer> ERROR
-
-%right '?' ':'
-%left ','
-%left OR
-%left AND
-%left '|'
-%left '^'
-%left '&'
-%left EQUAL NOTEQUAL
-%left '<' '>' LEQ GEQ
-%left LSH RSH
-%left '+' '-'
-%left '*' '/' '%'
-%right UNARY
-
-/* %expect 40 */
-
-%%
-
-start : exp1
- {
- expression_value = $1.value;
-#ifdef TEST_EXP_READER
- expression_signedp = $1.signedp;
-#endif
- }
- ;
-
-/* Expressions, including the comma operator. */
-exp1 : exp
- | exp1 ',' exp
- { if (pedantic)
- pedwarn ("comma operator in operand of `#if'");
- $$ = $3; }
- ;
-
-/* Expressions, not including the comma operator. */
-exp : '-' exp %prec UNARY
- { $$.value = - $2.value;
- $$.signedp = $2.signedp;
- if (($$.value & $2.value & $$.signedp) < 0)
- integer_overflow (); }
- | '!' exp %prec UNARY
- { $$.value = ! $2.value;
- $$.signedp = SIGNED; }
- | '+' exp %prec UNARY
- { $$ = $2; }
- | '~' exp %prec UNARY
- { $$.value = ~ $2.value;
- $$.signedp = $2.signedp; }
- | '#' NAME
- { $$.value = check_assertion ($2.address, $2.length,
- 0, NULL_PTR);
- $$.signedp = SIGNED; }
- | '#' NAME
- { keyword_parsing = 1; }
- '(' keywords ')'
- { $$.value = check_assertion ($2.address, $2.length,
- 1, $5);
- keyword_parsing = 0;
- $$.signedp = SIGNED; }
- | '(' exp1 ')'
- { $$ = $2; }
- ;
-
-/* Binary operators in order of decreasing precedence. */
-exp : exp '*' exp
- { $$.signedp = $1.signedp & $3.signedp;
- if ($$.signedp)
- {
- $$.value = $1.value * $3.value;
- if ($1.value
- && ($$.value / $1.value != $3.value
- || ($$.value & $1.value & $3.value) < 0))
- integer_overflow ();
- }
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- * $3.value); }
- | exp '/' exp
- { if ($3.value == 0)
- {
- if (!skip_evaluation)
- error ("division by zero in #if");
- $3.value = 1;
- }
- $$.signedp = $1.signedp & $3.signedp;
- if ($$.signedp)
- {
- $$.value = $1.value / $3.value;
- if (($$.value & $1.value & $3.value) < 0)
- integer_overflow ();
- }
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- / $3.value); }
- | exp '%' exp
- { if ($3.value == 0)
- {
- if (!skip_evaluation)
- error ("division by zero in #if");
- $3.value = 1;
- }
- $$.signedp = $1.signedp & $3.signedp;
- if ($$.signedp)
- $$.value = $1.value % $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- % $3.value); }
- | exp '+' exp
- { $$.value = $1.value + $3.value;
- $$.signedp = $1.signedp & $3.signedp;
- if (overflow_sum_sign ($1.value, $3.value,
- $$.value, $$.signedp))
- integer_overflow (); }
- | exp '-' exp
- { $$.value = $1.value - $3.value;
- $$.signedp = $1.signedp & $3.signedp;
- if (overflow_sum_sign ($$.value, $3.value,
- $1.value, $$.signedp))
- integer_overflow (); }
- | exp LSH exp
- { $$.signedp = $1.signedp;
- if (($3.value & $3.signedp) < 0)
- $$.value = right_shift (&$1, -$3.value);
- else
- $$.value = left_shift (&$1, $3.value); }
- | exp RSH exp
- { $$.signedp = $1.signedp;
- if (($3.value & $3.signedp) < 0)
- $$.value = left_shift (&$1, -$3.value);
- else
- $$.value = right_shift (&$1, $3.value); }
- | exp EQUAL exp
- { $$.value = ($1.value == $3.value);
- $$.signedp = SIGNED; }
- | exp NOTEQUAL exp
- { $$.value = ($1.value != $3.value);
- $$.signedp = SIGNED; }
- | exp LEQ exp
- { $$.signedp = SIGNED;
- if ($1.signedp & $3.signedp)
- $$.value = $1.value <= $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- <= $3.value); }
- | exp GEQ exp
- { $$.signedp = SIGNED;
- if ($1.signedp & $3.signedp)
- $$.value = $1.value >= $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- >= $3.value); }
- | exp '<' exp
- { $$.signedp = SIGNED;
- if ($1.signedp & $3.signedp)
- $$.value = $1.value < $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- < $3.value); }
- | exp '>' exp
- { $$.signedp = SIGNED;
- if ($1.signedp & $3.signedp)
- $$.value = $1.value > $3.value;
- else
- $$.value = ((unsigned HOST_WIDEST_INT) $1.value
- > $3.value); }
- | exp '&' exp
- { $$.value = $1.value & $3.value;
- $$.signedp = $1.signedp & $3.signedp; }
- | exp '^' exp
- { $$.value = $1.value ^ $3.value;
- $$.signedp = $1.signedp & $3.signedp; }
- | exp '|' exp
- { $$.value = $1.value | $3.value;
- $$.signedp = $1.signedp & $3.signedp; }
- | exp AND
- { skip_evaluation += !$1.value; }
- exp
- { skip_evaluation -= !$1.value;
- $$.value = ($1.value && $4.value);
- $$.signedp = SIGNED; }
- | exp OR
- { skip_evaluation += !!$1.value; }
- exp
- { skip_evaluation -= !!$1.value;
- $$.value = ($1.value || $4.value);
- $$.signedp = SIGNED; }
- | exp '?'
- { skip_evaluation += !$1.value; }
- exp ':'
- { skip_evaluation += !!$1.value - !$1.value; }
- exp
- { skip_evaluation -= !!$1.value;
- $$.value = $1.value ? $4.value : $7.value;
- $$.signedp = $4.signedp & $7.signedp; }
- | INT
- { $$ = yylval.integer; }
- | CHAR
- { $$ = yylval.integer; }
- | NAME
- { if (warn_undef && !skip_evaluation)
- warning ("`%.*s' is not defined",
- $1.length, $1.address);
- $$.value = 0;
- $$.signedp = SIGNED; }
- ;
-
-keywords :
- { $$ = 0; }
- | '(' keywords ')' keywords
- { struct arglist *temp;
- $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
- $$->next = $2;
- $$->name = (U_CHAR *) "(";
- $$->length = 1;
- temp = $$;
- while (temp != 0 && temp->next != 0)
- temp = temp->next;
- temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
- temp->next->next = $4;
- temp->next->name = (U_CHAR *) ")";
- temp->next->length = 1; }
- | NAME keywords
- { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
- $$->name = $1.address;
- $$->length = $1.length;
- $$->next = $2; }
- ;
-%%
-
-/* During parsing of a C expression, the pointer to the next character
- is in this variable. */
-
-static char *lexptr;
-
-/* Take care of parsing a number (anything that starts with a digit).
- Set yylval and return the token type; update lexptr.
- LEN is the number of characters in it. */
-
-/* maybe needs to actually deal with floating point numbers */
-
-static int
-parse_number (olen)
- int olen;
-{
- register char *p = lexptr;
- register int c;
- register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
- register int base = 10;
- register int len = olen;
- register int overflow = 0;
- register int digit, largest_digit = 0;
- int spec_long = 0;
-
- yylval.integer.signedp = SIGNED;
-
- if (*p == '0') {
- base = 8;
- if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
- p += 2;
- base = 16;
- len -= 2;
- }
- }
-
- max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
-
- for (; len > 0; len--) {
- c = *p++;
-
- if (c >= '0' && c <= '9')
- digit = c - '0';
- else if (base == 16 && c >= 'a' && c <= 'f')
- digit = c - 'a' + 10;
- else if (base == 16 && c >= 'A' && c <= 'F')
- digit = c - 'A' + 10;
- else {
- /* `l' means long, and `u' means unsigned. */
- while (1) {
- if (c == 'l' || c == 'L')
- {
- if (!pedantic < spec_long)
- yyerror ("too many `l's in integer constant");
- spec_long++;
- }
- else if (c == 'u' || c == 'U')
- {
- if (! yylval.integer.signedp)
- yyerror ("two `u's in integer constant");
- yylval.integer.signedp = UNSIGNED;
- }
- else {
- if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
- yyerror ("Floating point numbers not allowed in #if expressions");
- else
- yyerror ("missing white space after number `%.*s'",
- (int) (p - lexptr - 1), lexptr);
- }
-
- if (--len == 0)
- break;
- c = *p++;
- }
- /* Don't look for any more digits after the suffixes. */
- break;
- }
- if (largest_digit < digit)
- largest_digit = digit;
- nd = n * base + digit;
- overflow |= (max_over_base < n) | (nd < n);
- n = nd;
- }
-
- if (base <= largest_digit)
- pedwarn ("integer constant contains digits beyond the radix");
-
- if (overflow)
- pedwarn ("integer constant out of range");
-
- /* If too big to be signed, consider it unsigned. */
- if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
- {
- if (base == 10)
- warning ("integer constant is so large that it is unsigned");
- yylval.integer.signedp = UNSIGNED;
- }
-
- lexptr = p;
- yylval.integer.value = n;
- return INT;
-}
-
-struct token {
- const char *operator;
- int token;
-};
-
-static struct token tokentab2[] = {
- {"&&", AND},
- {"||", OR},
- {"<<", LSH},
- {">>", RSH},
- {"==", EQUAL},
- {"!=", NOTEQUAL},
- {"<=", LEQ},
- {">=", GEQ},
- {"++", ERROR},
- {"--", ERROR},
- {NULL, ERROR}
-};
-
-/* Read one token, getting characters through lexptr. */
-
-static int
-yylex ()
-{
- register int c;
- register int namelen;
- register unsigned char *tokstart;
- register struct token *toktab;
- int wide_flag;
- HOST_WIDEST_INT mask;
-
- retry:
-
- tokstart = (unsigned char *) lexptr;
- c = *tokstart;
- /* See if it is a special token of length 2. */
- if (! keyword_parsing)
- for (toktab = tokentab2; toktab->operator != NULL; toktab++)
- if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
- lexptr += 2;
- if (toktab->token == ERROR)
- yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
- return toktab->token;
- }
-
- switch (c) {
- case '\n':
- return 0;
-
- case ' ':
- case '\t':
- case '\r':
- lexptr++;
- goto retry;
-
- case 'L':
- /* Capital L may start a wide-string or wide-character constant. */
- if (lexptr[1] == '\'')
- {
- lexptr++;
- wide_flag = 1;
- mask = MAX_WCHAR_TYPE_MASK;
- goto char_constant;
- }
- if (lexptr[1] == '"')
- {
- lexptr++;
- wide_flag = 1;
- mask = MAX_WCHAR_TYPE_MASK;
- goto string_constant;
- }
- break;
-
- case '\'':
- wide_flag = 0;
- mask = MAX_CHAR_TYPE_MASK;
- char_constant:
- lexptr++;
- if (keyword_parsing) {
- char *start_ptr = lexptr - 1;
- while (1) {
- c = *lexptr++;
- if (c == '\\')
- c = parse_escape (&lexptr, mask);
- else if (c == '\'')
- break;
- }
- yylval.name.address = tokstart;
- yylval.name.length = lexptr - start_ptr;
- return NAME;
- }
-
- /* This code for reading a character constant
- handles multicharacter constants and wide characters.
- It is mostly copied from c-lex.c. */
- {
- register HOST_WIDEST_INT result = 0;
- register int num_chars = 0;
- int chars_seen = 0;
- unsigned width = MAX_CHAR_TYPE_SIZE;
- int max_chars;
-#ifdef MULTIBYTE_CHARS
- int longest_char = local_mb_cur_max ();
- char *token_buffer = (char *) alloca (longest_char);
- (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
-#endif
-
- max_chars = MAX_LONG_TYPE_SIZE / width;
- if (wide_flag)
- width = MAX_WCHAR_TYPE_SIZE;
-
- while (1)
- {
- c = *lexptr++;
-
- if (c == '\'' || c == EOF)
- break;
-
- ++chars_seen;
- if (c == '\\')
- {
- c = parse_escape (&lexptr, mask);
- }
- else
- {
-#ifdef MULTIBYTE_CHARS
- wchar_t wc;
- int i;
- int char_len = -1;
- for (i = 1; i <= longest_char; ++i)
- {
- token_buffer[i - 1] = c;
- char_len = local_mbtowc (& wc, token_buffer, i);
- if (char_len != -1)
- break;
- c = *lexptr++;
- }
- if (char_len > 1)
- {
- /* mbtowc sometimes needs an extra char before accepting */
- if (char_len < i)
- lexptr--;
- if (! wide_flag)
- {
- /* Merge character into result; ignore excess chars. */
- for (i = 1; i <= char_len; ++i)
- {
- if (i > max_chars)
- break;
- if (width < HOST_BITS_PER_INT)
- result = (result << width)
- | (token_buffer[i - 1]
- & ((1 << width) - 1));
- else
- result = token_buffer[i - 1];
- }
- num_chars += char_len;
- continue;
- }
- }
- else
- {
- if (char_len == -1)
- warning ("Ignoring invalid multibyte character");
- }
- if (wide_flag)
- c = wc;
-#endif /* ! MULTIBYTE_CHARS */
- }
-
- if (wide_flag)
- {
- if (chars_seen == 1) /* only keep the first one */
- result = c;
- continue;
- }
-
- /* Merge character into result; ignore excess chars. */
- num_chars++;
- if (num_chars <= max_chars)
- {
- if (width < HOST_BITS_PER_INT)
- result = (result << width) | (c & ((1 << width) - 1));
- else
- result = c;
- }
- }
-
- if (c != '\'')
- error ("malformatted character constant");
- else if (chars_seen == 0)
- error ("empty character constant");
- else if (num_chars > max_chars)
- {
- num_chars = max_chars;
- error ("character constant too long");
- }
- else if (chars_seen != 1 && ! traditional)
- warning ("multi-character character constant");
-
- /* If char type is signed, sign-extend the constant. */
- if (! wide_flag)
- {
- int num_bits = num_chars * width;
- if (num_bits == 0)
- /* We already got an error; avoid invalid shift. */
- yylval.integer.value = 0;
- else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
- sizeof ("__CHAR_UNSIGNED__") - 1, -1)
- || ((result >> (num_bits - 1)) & 1) == 0)
- yylval.integer.value
- = result & (~ (unsigned HOST_WIDEST_INT) 0
- >> (HOST_BITS_PER_WIDEST_INT - num_bits));
- else
- yylval.integer.value
- = result | ~(~ (unsigned HOST_WIDEST_INT) 0
- >> (HOST_BITS_PER_WIDEST_INT - num_bits));
- }
- else
- {
- yylval.integer.value = result;
- }
- }
-
- /* This is always a signed type. */
- yylval.integer.signedp = SIGNED;
-
- return CHAR;
-
- /* some of these chars are invalid in constant expressions;
- maybe do something about them later */
- case '/':
- case '+':
- case '-':
- case '*':
- case '%':
- case '|':
- case '&':
- case '^':
- case '~':
- case '!':
- case '@':
- case '<':
- case '>':
- case '[':
- case ']':
- case '.':
- case '?':
- case ':':
- case '=':
- case '{':
- case '}':
- case ',':
- case '#':
- if (keyword_parsing)
- break;
- case '(':
- case ')':
- lexptr++;
- return c;
-
- case '"':
- mask = MAX_CHAR_TYPE_MASK;
- string_constant:
- if (keyword_parsing) {
- char *start_ptr = lexptr;
- lexptr++;
- while (1) {
- c = *lexptr++;
- if (c == '\\')
- c = parse_escape (&lexptr, mask);
- else if (c == '"')
- break;
- }
- yylval.name.address = tokstart;
- yylval.name.length = lexptr - start_ptr;
- return NAME;
- }
- yyerror ("string constants not allowed in #if expressions");
- return ERROR;
- }
-
- if (c >= '0' && c <= '9' && !keyword_parsing) {
- /* It's a number */
- for (namelen = 1; ; namelen++) {
- int d = tokstart[namelen];
- if (! ((is_idchar[d] || d == '.')
- || ((d == '-' || d == '+')
- && (c == 'e' || c == 'E'
- || ((c == 'p' || c == 'P') && ! c89))
- && ! traditional)))
- break;
- c = d;
- }
- return parse_number (namelen);
- }
-
- /* It is a name. See how long it is. */
-
- if (keyword_parsing) {
- for (namelen = 0;; namelen++) {
- if (is_space[tokstart[namelen]])
- break;
- if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
- break;
- if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
- break;
- }
- } else {
- if (!is_idstart[c]) {
- yyerror ("Invalid token in expression");
- return ERROR;
- }
-
- for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
- ;
- }
-
- lexptr += namelen;
- yylval.name.address = tokstart;
- yylval.name.length = namelen;
- return NAME;
-}
-
-
-/* Parse a C escape sequence. STRING_PTR points to a variable
- containing a pointer to the string to parse. That pointer
- is updated past the characters we use. The value of the
- escape sequence is returned.
-
- RESULT_MASK is used to mask out the result;
- an error is reported if bits are lost thereby.
-
- A negative value means the sequence \ newline was seen,
- which is supposed to be equivalent to nothing at all.
-
- If \ is followed by a null character, we return a negative
- value and leave the string pointer pointing at the null character.
-
- If \ is followed by 000, we return 0 and leave the string pointer
- after the zeros. A value of 0 does not mean end of string. */
-
-HOST_WIDEST_INT
-parse_escape (string_ptr, result_mask)
- char **string_ptr;
- HOST_WIDEST_INT result_mask;
-{
- register int c = *(*string_ptr)++;
- switch (c)
- {
- case 'a':
- return TARGET_BELL;
- case 'b':
- return TARGET_BS;
- case 'e':
- case 'E':
- if (pedantic)
- pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
- return TARGET_ESC;
- case 'f':
- return TARGET_FF;
- case 'n':
- return TARGET_NEWLINE;
- case 'r':
- return TARGET_CR;
- case 't':
- return TARGET_TAB;
- case 'v':
- return TARGET_VT;
- case '\n':
- return -2;
- case 0:
- (*string_ptr)--;
- return 0;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- {
- register HOST_WIDEST_INT i = c - '0';
- register int count = 0;
- while (++count < 3)
- {
- c = *(*string_ptr)++;
- if (c >= '0' && c <= '7')
- i = (i << 3) + c - '0';
- else
- {
- (*string_ptr)--;
- break;
- }
- }
- if (i != (i & result_mask))
- {
- i &= result_mask;
- pedwarn ("octal escape sequence out of range");
- }
- return i;
- }
- case 'x':
- {
- register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
- register int digits_found = 0, digit;
- for (;;)
- {
- c = *(*string_ptr)++;
- if (c >= '0' && c <= '9')
- digit = c - '0';
- else if (c >= 'a' && c <= 'f')
- digit = c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
- digit = c - 'A' + 10;
- else
- {
- (*string_ptr)--;
- break;
- }
- overflow |= i ^ (i << 4 >> 4);
- i = (i << 4) + digit;
- digits_found = 1;
- }
- if (!digits_found)
- yyerror ("\\x used with no following hex digits");
- if (overflow | (i != (i & result_mask)))
- {
- i &= result_mask;
- pedwarn ("hex escape sequence out of range");
- }
- return i;
- }
- default:
- return c;
- }
-}
-
-static void
-integer_overflow ()
-{
- if (!skip_evaluation && pedantic)
- pedwarn ("integer overflow in preprocessor expression");
-}
-
-static HOST_WIDEST_INT
-left_shift (a, b)
- struct constant *a;
- unsigned HOST_WIDEST_INT b;
-{
- /* It's unclear from the C standard whether shifts can overflow.
- The following code ignores overflow; perhaps a C standard
- interpretation ruling is needed. */
- if (b >= HOST_BITS_PER_WIDEST_INT)
- return 0;
- else
- return (unsigned HOST_WIDEST_INT) a->value << b;
-}
-
-static HOST_WIDEST_INT
-right_shift (a, b)
- struct constant *a;
- unsigned HOST_WIDEST_INT b;
-{
- if (b >= HOST_BITS_PER_WIDEST_INT)
- return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0;
- else if (a->signedp)
- return a->value >> b;
- else
- return (unsigned HOST_WIDEST_INT) a->value >> b;
-}
-
-/* This page contains the entry point to this file. */
-
-/* Parse STRING as an expression, and complain if this fails
- to use up all of the contents of STRING.
- STRING may contain '\0' bytes; it is terminated by the first '\n'
- outside a string constant, so that we can diagnose '\0' properly.
- If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
- We do not support C comments. They should be removed before
- this function is called. */
-
-HOST_WIDEST_INT
-parse_c_expression (string, warn_undefined)
- char *string;
- int warn_undefined;
-{
- lexptr = string;
- warn_undef = warn_undefined;
-
- /* if there is some sort of scanning error, just return 0 and assume
- the parsing routine has printed an error message somewhere.
- there is surely a better thing to do than this. */
- if (setjmp (parse_return_error))
- return 0;
-
- if (yyparse () != 0)
- abort ();
-
- if (*lexptr != '\n')
- error ("Junk after end of expression.");
-
- return expression_value; /* set by yyparse () */
-}
-
-static void
-yyerror VPARAMS ((const char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, const char *);
-#endif
-
- verror (msgid, args);
- va_end (args);
- skip_evaluation = 0;
- longjmp (parse_return_error, 1);
-}
-
-
-#ifdef TEST_EXP_READER
-
-#if YYDEBUG
-extern int yydebug;
-#endif
-
-int pedantic;
-int traditional;
-int c89;
-
-int main PARAMS ((int, char **));
-static void initialize_random_junk PARAMS ((void));
-static void print_unsigned_host_widest_int PARAMS ((unsigned HOST_WIDEST_INT));
-
-/* Main program for testing purposes. */
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int n, c;
- char buf[1024];
- unsigned HOST_WIDEST_INT u;
-
- pedantic = 1 < argc;
- traditional = 2 < argc;
- c89 = 3 < argc;
-#if YYDEBUG
- yydebug = 4 < argc;
-#endif
- initialize_random_junk ();
-
- for (;;) {
- printf ("enter expression: ");
- n = 0;
- while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
- n++;
- if (c == EOF)
- break;
- parse_c_expression (buf, 1);
- printf ("parser returned ");
- u = (unsigned HOST_WIDEST_INT) expression_value;
- if (expression_value < 0 && expression_signedp) {
- u = -u;
- printf ("-");
- }
- if (u == 0)
- printf ("0");
- else
- print_unsigned_host_widest_int (u);
- if (! expression_signedp)
- printf("u");
- printf ("\n");
- }
-
- return 0;
-}
-
-static void
-print_unsigned_host_widest_int (u)
- unsigned HOST_WIDEST_INT u;
-{
- if (u) {
- print_unsigned_host_widest_int (u / 10);
- putchar ('0' + (int) (u % 10));
- }
-}
-
-/* table to tell if char can be part of a C identifier. */
-unsigned char is_idchar[256];
-/* table to tell if char can be first char of a c identifier. */
-unsigned char is_idstart[256];
-/* table to tell if c is horizontal or vertical space. */
-unsigned char is_space[256];
-
-/*
- * initialize random junk in the hash table and maybe other places
- */
-static void
-initialize_random_junk ()
-{
- register int i;
-
- /*
- * Set up is_idchar and is_idstart tables. These should be
- * faster than saying (is_alpha (c) || c == '_'), etc.
- * Must do set up these things before calling any routines tthat
- * refer to them.
- */
- for (i = 'a'; i <= 'z'; i++) {
- ++is_idchar[TOUPPER(i)];
- ++is_idchar[i];
- ++is_idstart[TOUPPER(i)];
- ++is_idstart[i];
- }
- for (i = '0'; i <= '9'; i++)
- ++is_idchar[i];
- ++is_idchar['_'];
- ++is_idstart['_'];
- ++is_idchar['$'];
- ++is_idstart['$'];
-
- ++is_space[' '];
- ++is_space['\t'];
- ++is_space['\v'];
- ++is_space['\f'];
- ++is_space['\n'];
- ++is_space['\r'];
-}
-
-void
-error VPARAMS ((char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, char *);
-#endif
-
- fprintf (stderr, "error: ");
- vfprintf (stderr, _(msgid), args);
- fprintf (stderr, "\n");
- va_end (args);
-}
-
-void
-pedwarn VPARAMS ((char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, char *);
-#endif
-
- fprintf (stderr, "pedwarn: ");
- vfprintf (stderr, _(msgid), args);
- fprintf (stderr, "\n");
- va_end (args);
-}
-
-void
-warning VPARAMS ((char * msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char * msgid;
-#endif
- va_list args;
-
- VA_START (args, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (args, char *);
-#endif
-
- fprintf (stderr, "warning: ");
- vfprintf (stderr, _(msgid), args);
- fprintf (stderr, "\n");
- va_end (args);
-}
-
-
-int
-check_assertion (name, sym_length, tokens_specified, tokens)
- U_CHAR *name;
- int sym_length;
- int tokens_specified;
- struct arglist *tokens;
-{
- return 0;
-}
-
-struct hashnode *
-lookup (name, len, hash)
- U_CHAR *name;
- int len;
- int hash;
-{
- return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
-}
-
-PTR
-xmalloc (size)
- size_t size;
-{
- return (PTR) malloc (size);
-}
-#endif
diff --git a/gcc/ch/ChangeLog b/gcc/ch/ChangeLog
index 4b7e2253abb..9e6eb47f5f4 100644
--- a/gcc/ch/ChangeLog
+++ b/gcc/ch/ChangeLog
@@ -1,3 +1,7 @@
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * ch/lex.c: Remove references to cccp.c.
+
2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
* lang-specs.h: Pass -fno-show-column to the preprocessor.
diff --git a/gcc/ch/decl.c b/gcc/ch/decl.c
index ddeb45f94f2..83caf0b003d 100644
--- a/gcc/ch/decl.c
+++ b/gcc/ch/decl.c
@@ -619,9 +619,7 @@ const char *chill_tree_code_name[] = {
};
#undef DEFTREECODE
-/* Nonzero means `$' can be in an identifier.
- See cccp.c for reasons why this breaks some obscure ANSI C programs. */
-
+/* Nonzero means `$' can be in an identifier. */
#ifndef DOLLARS_IN_IDENTIFIERS
#define DOLLARS_IN_IDENTIFIERS 0
#endif
diff --git a/gcc/ch/lex.c b/gcc/ch/lex.c
index 21a9aa0d60e..5f0eb524d11 100644
--- a/gcc/ch/lex.c
+++ b/gcc/ch/lex.c
@@ -1677,7 +1677,7 @@ check_newline ()
&& getlc (finput) == 't'
&& ((c = getlc (finput)) == ' ' || c == '\t'))
{
- /* #ident. The pedantic warning is now in cccp.c. */
+ /* #ident. The pedantic warning is now in cpp. */
/* Here we have just seen `#ident '.
A string constant should follow. */
diff --git a/gcc/config.in b/gcc/config.in
index f623b490d1f..9a178dbd6c1 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -203,9 +203,6 @@
/* Define if the `long double' type works. */
#undef HAVE_LONG_DOUBLE
-/* Define if you have a working `mmap' system call. */
-#undef HAVE_MMAP
-
/* Define if you have the ANSI # stringizing operator in cpp. */
#undef HAVE_STRINGIZE
@@ -422,6 +419,12 @@
/* Define if you have the i library (-li). */
#undef HAVE_LIBI
+/* Define if enumerated bitfields are treated as unsigned values. */
+#undef ENUM_BITFIELDS_ARE_UNSIGNED
+
/* Define if mmap can get us zeroed pages from /dev/zero. */
#undef HAVE_MMAP_ANYWHERE
+/* Define if read-only mmap of a plain file works. */
+#undef HAVE_MMAP_FILE
+
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 64320c7ada6..8bccbc5e4ea 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -20,8 +20,7 @@
Boston, MA 02111-1307, USA. */
#include "config.h"
-#include <stdio.h>
-#include <string.h>
+#include "system.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
diff --git a/gcc/config/convex/convex.h b/gcc/config/convex/convex.h
index 86dc07ea1ab..f59959f5775 100644
--- a/gcc/config/convex/convex.h
+++ b/gcc/config/convex/convex.h
@@ -491,7 +491,6 @@ extern int target_flags;
#define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 64
#define LONG_DOUBLE_TYPE_SIZE 64
-/* This prevents cexp.c from depending on LONG_TYPE_SIZE. */
#define MAX_LONG_TYPE_SIZE 64
/* Declare the standard types used by builtins to match convex stddef.h --
diff --git a/gcc/config/fx80/fx80.h b/gcc/config/fx80/fx80.h
index 35a9211dadc..ec320102a3e 100644
--- a/gcc/config/fx80/fx80.h
+++ b/gcc/config/fx80/fx80.h
@@ -179,9 +179,7 @@ extern int target_flags;
#define INT_TYPE_SIZE (TARGET_SHORT ? 16 : 32)
-/* Define these to avoid dependence on meaning of `int'.
- Note that WCHAR_TYPE_SIZE is used in cexp.y,
- where TARGET_SHORT is not available. */
+/* Define these to avoid dependence on meaning of `int'. */
#define WCHAR_TYPE "long int"
#define WCHAR_TYPE_SIZE 32
diff --git a/gcc/config/i370/i370.c b/gcc/config/i370/i370.c
index 1e07775247c..8d00f7330c5 100644
--- a/gcc/config/i370/i370.c
+++ b/gcc/config/i370/i370.c
@@ -645,7 +645,7 @@ mvs_add_label (id)
fwd_distance = lp->label_last_ref - lp->label_addr;
- if (mvs_page_code + 2*fwd_distance + mvs_page_lit < 4060) return;
+ if (mvs_page_code + 2 * fwd_distance + mvs_page_lit < 4060) return;
mvs_need_base_reload ++;
}
diff --git a/gcc/config/i370/i370.h b/gcc/config/i370/i370.h
index 08ac64484ce..88f5dd1264b 100644
--- a/gcc/config/i370/i370.h
+++ b/gcc/config/i370/i370.h
@@ -1160,23 +1160,29 @@ enum reg_class
fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM); \
}
-/* Generate case label. */
-/* hack alert -- I don't get it ... what if its a really big case label?
- * wouldn't we have to say label_emitted also ?? */
+/* Generate case label. For HLASM we can change to the data CSECT
+ and put the vectors out of the code body. The assembler just
+ concatenates CSECTs with the same name. */
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
- fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM)
+ fprintf (FILE, "\tDS\t0F\n"); \
+ fprintf (FILE,"\tCSECT\n"); \
+ fprintf (FILE, "%s%d\tEQU\t*\n", PREFIX, NUM)
+
+/* Put the CSECT back to the code body */
+
+#define ASM_OUTPUT_CASE_END(FILE, NUM, TABLE) \
+ assemble_name (FILE, mvs_function_name); \
+ fputs ("\tCSECT\n", FILE);
/* This is how to output an element of a case-vector that is absolute. */
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- mvs_check_page (FILE, 4, 0); \
fprintf (FILE, "\tDC\tA(L%d)\n", VALUE)
/* This is how to output an element of a case-vector that is relative. */
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- mvs_check_page (FILE, 4, 0); \
fprintf (FILE, "\tDC\tA(L%d-L%d)\n", VALUE, REL)
/* This is how to output an insn to push a register on the stack.
@@ -1188,7 +1194,7 @@ enum reg_class
#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \
mvs_check_page (FILE, 8, 4); \
- fprintf (FILE, "\tSXXX\t13,=F'4'\n\tST\t%s,%d(13)\n", \
+ fprintf (FILE, "\tS\t13,=F'4'\n\tST\t%s,%d(13)\n", \
reg_names[REGNO], STACK_POINTER_OFFSET)
/* This is how to output an insn to pop a register from the stack.
@@ -1196,13 +1202,9 @@ enum reg_class
#define ASM_OUTPUT_REG_POP(FILE, REGNO) \
mvs_check_page (FILE, 8, 0); \
- fprintf (FILE, "\tL\t%s,%d(13)\n\tLAXXX\t13,4(13)\n", \
+ fprintf (FILE, "\tL\t%s,%d(13)\n\tLA\t13,4(13)\n", \
reg_names[REGNO], STACK_POINTER_OFFSET)
-/* TBD: hack alert XXX these two float point macros print horribly
- incorrect things when run in cross-compiler mode. Thats's because
- in cross-compiler mode, the VALUE is not really a double. See below,
- in the ELF section, for the correct implementation. */
/* This is how to output an assembler line defining a `double' constant. */
#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
fprintf (FILE, "\tDC\tD'%.18G'\n", (VALUE))
diff --git a/gcc/config/i370/i370.md b/gcc/config/i370/i370.md
index c3a3a981a4c..97081957f9f 100644
--- a/gcc/config/i370/i370.md
+++ b/gcc/config/i370/i370.md
@@ -170,7 +170,7 @@
{
/* an unsigned compare to zero is always zero/not-zero... */
mvs_check_page (0, 4, 4);
- return \"N %0,=X'000000FF'\";
+ return \"N %0,=XL4'000000FF'\";
}
mvs_check_page (0, 4, 0);
return \"CLI %0,0\";
@@ -189,7 +189,7 @@
{
/* an unsigned compare to zero is always zero/not-zero... */
mvs_check_page (0, 4, 4);
- return \"N %0,=X'000000FF'\";
+ return \"N %0,=XL4'000000FF'\";
}
mvs_check_page (0, 8, 0);
return \"SLL %0,24\;SRA %0,24\";
@@ -348,7 +348,7 @@
if (GET_CODE (operands[1]) == CONST_INT)
{
mvs_check_page (0, 4, 1);
- return \"CLM %0,1,=X'%X1'\";
+ return \"CLM %0,1,=XL1'%X1'\";
}
mvs_check_page (0, 4, 0);
return \"CLM %0,1,%1\";
@@ -359,7 +359,7 @@
if (REG_P (operands[1]))
{
mvs_check_page (0, 4, 1);
- return \"CLM %1,1,=X'%X0'\";
+ return \"CLM %1,1,=XL1'%X0'\";
}
mvs_check_page (0, 4, 0);
return \"CLI %1,%B0\";
@@ -394,7 +394,7 @@
if (GET_CODE (operands[1]) == CONST_INT)
{
mvs_check_page (0, 4, 1);
- return \"CLM %0,1,=X'%X1'\";
+ return \"CLM %0,1,=XL1'%X1'\";
}
if (!(REG_P (operands[1])))
{
@@ -648,9 +648,7 @@ check_label_emit ();
else if (REG_P (operands[1]))
{
mvs_check_page (0, 4, 0);
- /* can't use stm otherwise stm r6,r7,0(r10,r13) can happen */
return \"STM %1,%N1,%0\";
- /* return \"ST %1,%0\;ST %N1,4+%0\"; */
}
mvs_check_page (0, 6, 0);
return \"MVC %O0(8,%R0),%W1\";
@@ -706,17 +704,8 @@ check_label_emit ();
mvs_check_page (0, 4, 0);
return \"STD %1,%0\";
}
- else if (REG_P (operands[1]))
- {
- /* hack alert -- for some reason, %N0 doesn't work
- * when the mem ref is e.g. 168(r13,r1) ...
- * add 4 and pray for the best .. */
- mvs_check_page (0, 8, 0);
- return \"ST %1,%0\;ST %N1,4+%N0\";
- }
- /* this is almost certainly not what is desired, let it break ... */
- mvs_check_page (0, 8, 0);
- return \"xxxST %1,%0\;ST %N1,%N0\";
+ mvs_check_page (0, 4, 0);
+ return \"STM %1,%N1,%0\";
}"
[(set_attr "length" "8")]
)
@@ -740,16 +729,15 @@ check_label_emit ();
if (REG_P (operands[0]))
{
mvs_check_page (0, 8, 0);
- return \"L %0,%1\;L %N0,4+%N1\";
+ return \"LM %0,%N0,%1\";
}
else if (REG_P (operands[1]))
{
mvs_check_page (0, 8, 0);
- return \"ST %1,%0\;ST %N1,4+%N0\";
+ return \"STM %1,%N1,%0\";
}
mvs_check_page (0, 6, 0);
- /* should never get here ... */
- return \"xxxxxxMVC %O0(8,%R0),%W1\";
+ return \"MVC %O0(8,%R0),%1\";
}"
[(set_attr "length" "8")]
)
@@ -1200,7 +1188,7 @@ check_label_emit ();
return \"STM %1,%N1,%0\";
}
mvs_check_page (0, 6, 0);
- return \"MVC %O0(8,%R0),%W1\";
+ return \"MVC %O0(8,%R0),%1\";
}"
[(set_attr "length" "12")]
)
@@ -1715,7 +1703,7 @@ check_label_emit ();
/* AND only sets zero/not-zero bits not the arithmetic bits ... */
CC_STATUS_INIT;
mvs_check_page (0, 4, 4);
- return \"N %1,=X'0000FFFF'\";
+ return \"N %1,=XL4'0000FFFF'\";
}"
[(set_attr "length" "4")]
)
@@ -1736,7 +1724,7 @@ check_label_emit ();
/* AND only sets zero/not-zero bits not the arithmetic bits ... */
CC_STATUS_INIT;
mvs_check_page (0, 4, 4);
- return \"N %0,=X'000000FF'\";
+ return \"N %0,=XL4'000000FF'\";
}
if (GET_CODE (operands[1]) == CONST_INT)
{
@@ -1766,7 +1754,7 @@ check_label_emit ();
/* AND only sets zero/not-zero bits not the arithmetic bits ... */
CC_STATUS_INIT;
mvs_check_page (0, 4, 4);
- return \"N %0,=X'000000FF'\";
+ return \"N %0,=XL4'000000FF'\";
}
if (GET_CODE (operands[1]) == CONST_INT)
{
@@ -1830,6 +1818,8 @@ check_label_emit ();
;
; floatsidf2 instruction pattern(s).
;
+; LE/370 mode uses the float field of the TCA.
+;
(define_insn "floatsidf2"
[(set (match_operand:DF 0 "general_operand" "=f")
@@ -1839,10 +1829,15 @@ check_label_emit ();
{
check_label_emit ();
CC_STATUS_INIT;
+#ifdef TARGET_ELF_ABI
+ mvs_check_page (0, 22, 12);
+ return \"MVC 140(4,13),=XL4'4E000000'\;ST %1,144(,13)\;XI 144(13),128\;LD %0,140(,13)\;SD %0,=XL8'4E00000080000000'\";
+#else
mvs_check_page (0, 16, 8);
- return \"ST %1,144(,13)\;XI 144(13),128\;LD %0,140(,13)\;SD %0,=XL8'4E00000080000000'\";
+ return \"ST %1,508(,12)\;XI 508(12),128\;LD %0,504(,12)\;SD %0,=XL8'4E00000080000000'\";
+#endif
}"
- [(set_attr "length" "16")]
+ [(set_attr "length" "22")]
)
;
@@ -2419,7 +2414,7 @@ check_label_emit ();
/* XXX trouble. Below we generate some rtx's that model what
* is really supposed to happen with multiply on the 370/390
- * hardware, and that is all well & god. However, during optimization
+ * hardware, and that is all well & good. However, during optimization
* it can happen that the two operands are exchanged (after all,
* multiplication is commutitive), in which case the doubleword
* ends up in memory and everything is hosed. The gen_reg_rtx
@@ -3579,7 +3574,7 @@ check_label_emit ();
return \"X %0,=F'-1'\";
}
mvs_check_page (0, 6, 4);
- return \"XC %O0(2,%R0),=X'FFFF'\";
+ return \"XC %O0(2,%R0),=XL4'FFFF'\";
}"
[(set_attr "length" "6")]
)
@@ -3867,10 +3862,10 @@ check_label_emit ();
if (REG_P (operands[2]))
{
mvs_check_page (0, 8, 4);
- return \"N %0,=X'0000FFFF'\;SRL %0,0(%2)\";
+ return \"N %0,=XL4'0000FFFF'\;SRL %0,0(%2)\";
}
mvs_check_page (0, 8, 4);
- return \"N %0,=X'0000FFFF'\;SRL %0,%c2\";
+ return \"N %0,=XL4'0000FFFF'\;SRL %0,%c2\";
}"
[(set_attr "length" "8")]
)
@@ -3890,8 +3885,8 @@ check_label_emit ();
CC_STATUS_INIT; /* AND sets the CC but not how we want it */
mvs_check_page (0, 8, 4);
if (REG_P (operands[2]))
- return \"N %0,=X'000000FF'\;SRL %0,0(%2)\";
- return \"N %0,=X'000000FF'\;SRL %0,%c2\";
+ return \"N %0,=XL4'000000FF'\;SRL %0,0(%2)\";
+ return \"N %0,=XL4'000000FF'\;SRL %0,%c2\";
}"
[(set_attr "length" "8")]
)
diff --git a/gcc/config/i370/oe.h b/gcc/config/i370/oe.h
index 62900520b87..634252ee65b 100644
--- a/gcc/config/i370/oe.h
+++ b/gcc/config/i370/oe.h
@@ -29,6 +29,10 @@ Boston, MA 02111-1307, USA. */
#define TARGET_EBCDIC 1
#define TARGET_HLASM 1
+/* Options for the preprocessor for this target machine. */
+
+#define CPP_SPEC "-trigraphs"
+
/* Options for this target machine. */
#define LIB_SPEC ""
diff --git a/gcc/config/i370/xm-oe.h b/gcc/config/i370/xm-oe.h
index 370ec09c9c4..a930a2bae61 100644
--- a/gcc/config/i370/xm-oe.h
+++ b/gcc/config/i370/xm-oe.h
@@ -34,7 +34,7 @@ Boston, MA 02111-1307, USA. */
#define HOST_BITS_PER_SHORT 16
#define HOST_BITS_PER_INT 32
#define HOST_BITS_PER_LONG 32
-#define HOST_BITS_PER_LONGLONG 64
+#define HOST_BITS_PER_LONGLONG 32
#define HOST_FLOAT_FORMAT IBM_FLOAT_FORMAT
#define HOST_EBCDIC 1
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d5ebd677dd4..b2e81a47e2a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -163,12 +163,12 @@ struct processor_costs k6_cost = {
struct processor_costs athlon_cost = {
1, /* cost of an add instruction */
- 1, /* cost of a lea instruction */
+ 2, /* cost of a lea instruction */
1, /* variable shift costs */
1, /* constant shift costs */
5, /* cost of starting a multiply */
0, /* cost of multiply per each bit set */
- 19, /* cost of a divide/mod */
+ 42, /* cost of a divide/mod */
8, /* "large" insn */
9, /* MOVE_RATIO */
4, /* cost for loading QImode using movzbl */
@@ -177,9 +177,9 @@ struct processor_costs athlon_cost = {
Relative to reg-reg move (2). */
{2, 3, 2}, /* cost of storing integer registers */
4, /* cost of reg,reg fld/fst */
- {6, 6, 6}, /* cost of loading fp registers
+ {6, 6, 20}, /* cost of loading fp registers
in SFmode, DFmode and XFmode */
- {4, 4, 4} /* cost of loading integer registers */
+ {4, 4, 16} /* cost of loading integer registers */
};
struct processor_costs *ix86_cost = &pentium_cost;
@@ -222,6 +222,9 @@ const int x86_sub_esp_4 = m_ATHLON | m_PPRO;
const int x86_sub_esp_8 = m_ATHLON | m_PPRO | m_386 | m_486;
const int x86_add_esp_4 = m_ATHLON | m_K6;
const int x86_add_esp_8 = m_ATHLON | m_PPRO | m_K6 | m_386 | m_486;
+const int x86_integer_DFmode_moves = ~m_ATHLON;
+const int x86_partial_reg_dependency = m_ATHLON;
+const int x86_memory_mismatch_stall = m_ATHLON;
#define AT_BP(mode) (gen_rtx_MEM ((mode), hard_frame_pointer_rtx))
@@ -2106,11 +2109,11 @@ ix86_expand_epilogue (emit_return)
{
rtx popc = GEN_INT (current_function_pops_args);
- /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
- asked to pop more, pop return address, do explicit add, and jump
- indirectly to the caller. */
+ /* i386 can only pop 64K bytes. If asked to pop more, pop
+ return address, do explicit add, and jump indirectly to the
+ caller. */
- if (current_function_pops_args >= 32768)
+ if (current_function_pops_args >= 65536)
{
rtx ecx = gen_rtx_REG (SImode, 2);
@@ -6287,6 +6290,7 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
int cost;
{
enum attr_type insn_type, dep_insn_type;
+ enum attr_memory memory;
rtx set, set2;
int dep_insn_code_number;
@@ -6334,7 +6338,8 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
increase the cost here for non-imov insns. */
if (dep_insn_type != TYPE_IMOV
&& dep_insn_type != TYPE_FMOV
- && get_attr_memory (dep_insn) == MEMORY_LOAD)
+ && ((memory = get_attr_memory (dep_insn) == MEMORY_LOAD)
+ || memory == MEMORY_BOTH))
cost += 1;
/* INT->FP conversion is expensive. */
@@ -6359,7 +6364,8 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
/* Since we can't represent delayed latencies of load+operation,
increase the cost here for non-imov insns. */
- if (get_attr_memory (dep_insn) == MEMORY_LOAD)
+ if ((memory = get_attr_memory (dep_insn) == MEMORY_LOAD)
+ || memory == MEMORY_BOTH)
cost += (dep_insn_type != TYPE_IMOV) ? 2 : 1;
/* INT->FP conversion is expensive. */
@@ -6368,19 +6374,15 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
break;
case PROCESSOR_ATHLON:
- /* Address Generation Interlock cause problems on the Athlon CPU because
- the loads and stores are done in order so once one load or store has
- to wait, others must too, so penalize the AGIs slightly by one cycle.
- We might experiment with this value later. */
- if (ix86_agi_dependant (insn, dep_insn, insn_type))
- cost += 1;
+ if ((memory = get_attr_memory (dep_insn)) == MEMORY_LOAD
+ || memory == MEMORY_BOTH)
+ {
+ if (dep_insn_type == TYPE_IMOV || dep_insn_type == TYPE_FMOV)
+ cost += 2;
+ else
+ cost += 3;
+ }
- /* Since we can't represent delayed latencies of load+operation,
- increase the cost here for non-imov insns. */
- if (dep_insn_type != TYPE_IMOV
- && dep_insn_type != TYPE_FMOV
- && get_attr_memory (dep_insn) == MEMORY_LOAD)
- cost += 2;
default:
break;
}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 50f08251420..8ae7be8d444 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -173,8 +173,9 @@ extern const int x86_use_cltd, x86_read_modify_write;
extern const int x86_read_modify, x86_split_long_moves;
extern const int x86_promote_QImode, x86_single_stringop;
extern const int x86_himode_math, x86_qimode_math, x86_promote_qi_regs;
-extern const int x86_promote_hi_regs;
+extern const int x86_promote_hi_regs, x86_integer_DFmode_moves;
extern const int x86_add_esp_4, x86_add_esp_8, x86_sub_esp_4, x86_sub_esp_8;
+extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
#define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
#define TARGET_PUSH_MEMORY (x86_push_memory & CPUMASK)
@@ -206,6 +207,9 @@ extern const int x86_add_esp_4, x86_add_esp_8, x86_sub_esp_4, x86_sub_esp_8;
#define TARGET_ADD_ESP_8 (x86_add_esp_8 & CPUMASK)
#define TARGET_SUB_ESP_4 (x86_sub_esp_4 & CPUMASK)
#define TARGET_SUB_ESP_8 (x86_sub_esp_8 & CPUMASK)
+#define TARGET_INTEGER_DFMODE_MOVES (x86_integer_DFmode_moves & CPUMASK)
+#define TARGET_PARTIAL_REG_DEPENDENCY (x86_partial_reg_dependency & CPUMASK)
+#define TARGET_MEMORY_MISMATCH_STALL (x86_memory_mismatch_stall & CPUMASK)
#define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE)
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 090d0ebd444..8b9b2530e78 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -738,7 +738,7 @@
;; communicates with all the execution units seperately instead.
(define_attr "athlon_decode" "direct,vector"
- (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str")
+ (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
(const_string "vector")
(and (eq_attr "type" "push")
(match_operand 1 "memory_operand" ""))
@@ -766,7 +766,7 @@
(define_function_unit "athlon_ieu" 3 0
(and (eq_attr "cpu" "athlon")
- (eq_attr "type" "alu1,negnot,alu,icmp,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,str,cld"))
+ (eq_attr "type" "alu1,negnot,alu,icmp,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
1 1)
(define_function_unit "athlon_ieu" 3 0
@@ -777,12 +777,12 @@
(define_function_unit "athlon_ieu" 3 0
(and (eq_attr "cpu" "athlon")
(eq_attr "type" "imul"))
- 4 0)
+ 5 0)
(define_function_unit "athlon_ieu" 3 0
(and (eq_attr "cpu" "athlon")
(eq_attr "type" "idiv"))
- 27 0)
+ 42 0)
(define_function_unit "athlon_muldiv" 1 0
(and (eq_attr "cpu" "athlon")
@@ -792,56 +792,118 @@
(define_function_unit "athlon_muldiv" 1 0
(and (eq_attr "cpu" "athlon")
(eq_attr "type" "idiv"))
- 27 27)
+ 42 42)
-(define_attr "athlon_fpunits" "none,store,mul,add,muladd,all"
+(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
(cond [(eq_attr "type" "fop,fop1,fcmp")
(const_string "add")
- (eq_attr "type" "fmul,fdiv,fpspc,fsgn")
+ (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
(const_string "mul")
- (and (eq_attr "type" "fmov") (eq_attr "memory" "!none"))
+ (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
(const_string "store")
+ (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
+ (const_string "any")
(and (eq_attr "type" "fmov")
(ior (match_operand:SI 1 "register_operand" "")
(match_operand 1 "immediate_operand" "")))
(const_string "store")
(eq_attr "type" "fmov")
- (const_string "muladd")
- (eq_attr "type" "fcmov")
- (const_string "all")]
+ (const_string "muladd")]
(const_string "none")))
-(define_function_unit "athlon_fp_mul" 1 0
+;; We use latencies 1 for definitions. This is OK to model colisions
+;; in execution units. The real latencies are modeled in the "fp" pipeline.
+
+;; fsin, fcos: 96-192
+;; fsincos: 107-211
+;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
+(define_function_unit "athlon_fp" 3 0
(and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "mul,all"))
- 4 1)
+ (eq_attr "type" "fpspc"))
+ 100 1)
-(define_function_unit "athlon_fp_add" 1 0
+;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
+(define_function_unit "athlon_fp" 3 0
(and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "add,all"))
+ (eq_attr "type" "fdiv"))
+ 24 1)
+
+(define_function_unit "athlon_fp" 3 0
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "fop,fop1,fmul"))
4 1)
-(define_function_unit "athlon_fp_muladd" 2 0
+;; XFmode loads are slow.
+;; XFmode store is slow too (8 cycles), but we don't need to model it, because
+;; there are no dependent instructions.
+
+(define_function_unit "athlon_fp" 3 0
(and (eq_attr "cpu" "athlon")
(and (eq_attr "type" "fmov")
- (eq_attr "athlon_fpunits" "muladd,mul,add,all")))
+ (match_operand:XF 1 "memory_operand" "")))
+ 10 1)
+
+(define_function_unit "athlon_fp" 3 0
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "fmov,fsgn"))
2 1)
+;; fcmp and ftst instructions
+(define_function_unit "athlon_fp" 3 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fcmp")
+ (eq_attr "athlon_decode" "direct")))
+ 3 1)
+
+;; fcmpi instructions.
+(define_function_unit "athlon_fp" 3 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fcmp")
+ (eq_attr "athlon_decode" "vector")))
+ 3 1)
+
+(define_function_unit "athlon_fp" 3 0
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "fcmov"))
+ 7 1)
+
+(define_function_unit "athlon_fp_mul" 1 0
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "athlon_fpunits" "mul"))
+ 1 1)
+
+(define_function_unit "athlon_fp_add" 1 0
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "athlon_fpunits" "add"))
+ 1 1)
+
(define_function_unit "athlon_fp_muladd" 2 0
(and (eq_attr "cpu" "athlon")
- (and (eq_attr "type" "!fmov")
- (eq_attr "athlon_fpunits" "muladd,mul,add,all")))
- 4 1)
+ (eq_attr "athlon_fpunits" "muladd,mul,add"))
+ 1 1)
(define_function_unit "athlon_fp_store" 1 0
(and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "store,all"))
+ (eq_attr "athlon_fpunits" "store"))
1 1)
-(define_function_unit "athlon_agu" 3 0
+;; We don't need to model the Adress Generation Unit, since we don't model
+;; the re-order buffer yet and thus we never schedule more than three operations
+;; at time. Later we may want to experiment with MD_SCHED macros modeling the
+;; decoders independently on the functional units.
+
+;(define_function_unit "athlon_agu" 3 0
+; (and (eq_attr "cpu" "athlon")
+; (and (eq_attr "memory" "!none")
+; (eq_attr "athlon_fpunits" "none")))
+; 1 1)
+
+;; Model load unit to avoid too long sequences of loads. We don't need to
+;; model store queue, since it is hardly going to be bottleneck.
+
+(define_function_unit "athlon_load" 2 0
(and (eq_attr "cpu" "athlon")
- (and (eq_attr "memory" "!none")
- (eq_attr "athlon_fpunits" "none")))
+ (eq_attr "memory" "load,both"))
1 1)
@@ -1255,6 +1317,7 @@
""
"sahf"
[(set_attr "length" "1")
+ (set_attr "athlon_decode" "vector")
(set_attr "ppro_uops" "one")])
;; Pentium Pro can do steps 1 through 3 in one go.
@@ -1390,6 +1453,7 @@
"xchg{l}\\t%1, %0"
[(set_attr "type" "imov")
(set_attr "pent_pair" "np")
+ (set_attr "athlon_decode" "vector")
(set_attr "ppro_uops" "few")])
(define_expand "movhi"
@@ -1437,8 +1501,10 @@
}"
[(set (attr "type")
(cond [(and (eq_attr "alternative" "0")
- (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
- (const_int 0)))
+ (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
+ (const_int 0))
+ (eq (symbol_ref "TARGET_HIMODE_MATH")
+ (const_int 0))))
(const_string "imov")
(and (eq_attr "alternative" "1,2")
(match_operand:HI 1 "aligned_operand" ""))
@@ -1456,8 +1522,10 @@
(match_operand:HI 1 "aligned_operand" ""))
(const_string "0")
(and (eq_attr "alternative" "0")
- (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
- (const_int 0)))
+ (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
+ (const_int 0))
+ (eq (symbol_ref "TARGET_HIMODE_MATH")
+ (const_int 0))))
(const_string "0")
]
(const_string "1")))
@@ -1547,9 +1615,19 @@
[(set_attr "type" "pop")
(set_attr "length_prefix" "1")])
+;; Situation is quite tricky about when to choose full sized (SImode) move
+;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
+;; partial register dependency machines (such as AMD Athlon), where QImode
+;; moves issue extra dependency and for partial register stalls machines
+;; that don't use QImode patterns (and QImode move cause stall on the next
+;; instruction).
+;;
+;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
+;; register stall machines with, where we use QImode instructions, since
+;; partial register stall can be caused there. Then we use movzx.
(define_insn "*movqi_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,r,?r,m")
- (match_operand:QI 1 "general_operand" "qn,qm,rn,qm,qn"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
+ (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"*
{
@@ -1560,26 +1638,50 @@
abort ();
return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
default:
- if (which_alternative == 2)
+ if (which_alternative == 4 || which_alternative == 3
+ || (which_alternative == 1 && get_attr_length (insn) == 5)
+ || (which_alternative == 0
+ && ((TARGET_PARTIAL_REG_STALL && !TARGET_QIMODE_MATH)
+ || TARGET_PARTIAL_REG_DEPENDENCY)))
return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
else
return \"mov{b}\\t{%1, %0|%0, %1}\";
}
}"
[(set (attr "type")
- (cond [(eq_attr "alternative" "3")
+ (cond [(and (eq_attr "alternative" "3")
+ (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
+ (const_int 0))
+ (eq (symbol_ref "TARGET_QIMODE_MATH")
+ (const_int 0))))
+ (const_string "imov")
+ (eq_attr "alternative" "3,5")
(const_string "imovx")
(and (ne (symbol_ref "TARGET_MOVX")
(const_int 0))
- (eq_attr "alternative" "1"))
+ (eq_attr "alternative" "2"))
(const_string "imovx")
]
(const_string "imov")))
; There's no place to override just the immediate length
(set (attr "length")
(cond [(and (eq_attr "type" "imov")
- (and (eq_attr "alternative" "2")
- (match_operand:HI 1 "immediate_operand" "")))
+ (and (match_operand:HI 1 "immediate_operand" "")
+ (eq_attr "alternative" "4")))
+ (const_string "5")
+ ;; Avoid extra dependency on partial register.
+ (and (eq_attr "type" "imov")
+ (and (eq_attr "alternative" "1")
+ (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
+ (const_int 0))))
+ (const_string "5")
+ ;; Avoid partial register stalls when not using QImode arithmetic
+ (and (eq_attr "type" "imov")
+ (and (eq_attr "alternative" "1")
+ (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
+ (const_int 0))
+ (eq (symbol_ref "TARGET_QIMODE_MATH")
+ (const_int 0)))))
(const_string "5")
]
(const_string "*")))])
@@ -1904,10 +2006,38 @@
;; On the average, pushdf using integers can be still shorter. Allow this
;; pattern for optimize_size too.
-(define_insn "*pushdf"
+(define_insn "*pushdf_nointeger"
+ [(set (match_operand:DF 0 "push_operand" "=<,<,<")
+ (match_operand:DF 1 "general_no_elim_operand" "f,Fo#f,*r#f"))]
+ "!TARGET_INTEGER_DFMODE_MOVES"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ /* %%% We loose REG_DEAD notes for controling pops if we split late. */
+ operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
+ operands[2] = stack_pointer_rtx;
+ operands[3] = GEN_INT (8);
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
+ else
+ return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
+
+ case 1:
+ case 2:
+ return \"#\";
+
+ default:
+ abort ();
+ }
+}"
+ [(set_attr "type" "multi")])
+
+(define_insn "*pushdf_integer"
[(set (match_operand:DF 0 "push_operand" "=<,<")
(match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
- ""
+ "TARGET_INTEGER_DFMODE_MOVES"
"*
{
switch (which_alternative)
@@ -1955,7 +2085,7 @@
[(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
(match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
- && optimize_size
+ && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
&& (reload_in_progress || reload_completed
|| GET_CODE (operands[1]) != CONST_DOUBLE
|| memory_operand (operands[0], DFmode))"
@@ -2002,7 +2132,7 @@
[(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
(match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
- && !optimize_size
+ && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
&& (reload_in_progress || reload_completed
|| GET_CODE (operands[1]) != CONST_DOUBLE
|| memory_operand (operands[0], DFmode))"
@@ -2304,7 +2434,8 @@
else
return \"fxch\\t%0\";
}"
- [(set_attr "type" "fxch")])
+ [(set_attr "type" "fxch")
+ (set_attr "athlon_decode" "vector")])
;; Zero extension instructions
@@ -3202,6 +3333,7 @@
"TARGET_80387"
"fldcw\\t%0"
[(set_attr "length_opcode" "2")
+ (set_attr "athlon_decode" "vector")
(set_attr "ppro_uops" "few")])
;; Conversion between fixed point and floating point.
@@ -7691,6 +7823,7 @@
""
"leave"
[(set_attr "length" "1")
+ (set_attr "athlon_decode" "vector")
(set_attr "ppro_uops" "few")])
(define_expand "ffssi2"
@@ -8123,7 +8256,8 @@
(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
"fsqrt"
- [(set_attr "type" "fpspc")])
+ [(set_attr "type" "fpspc")
+ (set_attr "athlon_decode" "direct")])
(define_insn "sqrtdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
@@ -8131,7 +8265,8 @@
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& (TARGET_IEEE_FP || flag_fast_math) "
"fsqrt"
- [(set_attr "type" "fpspc")])
+ [(set_attr "type" "fpspc")
+ (set_attr "athlon_decode" "direct")])
(define_insn "*sqrtextendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
@@ -8139,7 +8274,8 @@
(match_operand:SF 1 "register_operand" "0"))))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
"fsqrt"
- [(set_attr "type" "fpspc")])
+ [(set_attr "type" "fpspc")
+ (set_attr "athlon_decode" "direct")])
(define_insn "sqrtxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
@@ -8147,7 +8283,8 @@
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& (TARGET_IEEE_FP || flag_fast_math) "
"fsqrt"
- [(set_attr "type" "fpspc")])
+ [(set_attr "type" "fpspc")
+ (set_attr "athlon_decode" "direct")])
(define_insn "*sqrtextenddfxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
@@ -8155,7 +8292,8 @@
(match_operand:DF 1 "register_operand" "0"))))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
"fsqrt"
- [(set_attr "type" "fpspc")])
+ [(set_attr "type" "fpspc")
+ (set_attr "athlon_decode" "direct")])
(define_insn "*sqrtextendsfxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
@@ -8163,7 +8301,8 @@
(match_operand:SF 1 "register_operand" "0"))))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
"fsqrt"
- [(set_attr "type" "fpspc")])
+ [(set_attr "type" "fpspc")
+ (set_attr "athlon_decode" "direct")])
(define_insn "sindf2"
[(set (match_operand:DF 0 "register_operand" "=f")
diff --git a/gcc/config/i386/xm-os2.h b/gcc/config/i386/xm-os2.h
index b8a5ad057a3..83476c0a87d 100644
--- a/gcc/config/i386/xm-os2.h
+++ b/gcc/config/i386/xm-os2.h
@@ -36,7 +36,6 @@ Boston, MA 02111-1307, USA. */
#ifdef __EMX__
#define EMX
#define USG
-#define BSTRING
#define HAVE_PUTENV
#define HAVE_VPRINTF
#define HAVE_STRERROR
diff --git a/gcc/config/i386/xm-sco.h b/gcc/config/i386/xm-sco.h
index ad634499d30..36d65e569c3 100644
--- a/gcc/config/i386/xm-sco.h
+++ b/gcc/config/i386/xm-sco.h
@@ -3,11 +3,3 @@
/* Big buffers improve performance. */
#define IO_BUFFER_SIZE (0x8000 - 1024)
-
-#ifndef __GNUC__
-/* The SCO compiler gets it wrong, and treats enumerated bitfields
- as signed quantities, making it impossible to use an 8-bit enum
- for compiling GNU C++. */
-#define ONLY_INT_FIELDS 1
-#define CODE_FIELD_BUG 1
-#endif
diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h
index 6e5efdb89d6..95f73a34847 100644
--- a/gcc/config/ia64/sysv4.h
+++ b/gcc/config/ia64/sysv4.h
@@ -206,6 +206,10 @@ do { \
else \
data_section (); \
} \
+ /* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL, \
+ in which case we can't put it in a shared library rodata. */ \
+ else if (flag_pic && (RELOC)) \
+ data_section (); \
else \
const_section (); \
}
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 5d170429bf0..acde9c099b7 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -337,10 +337,8 @@ extern int target_flags;
#define INT_TYPE_SIZE (TARGET_SHORT ? 16 : 32)
-/* Define these to avoid dependence on meaning of `int'.
- Note that WCHAR_TYPE_SIZE is used in cexp.y,
- where TARGET_SHORT is not available. */
-
+/* Define these to avoid dependence on meaning of `int'. */
+
#define WCHAR_TYPE "long int"
#define WCHAR_TYPE_SIZE 32
diff --git a/gcc/config/m68k/x-apollo68 b/gcc/config/m68k/x-apollo68
index 9d4f863955c..b1bfa252c99 100644
--- a/gcc/config/m68k/x-apollo68
+++ b/gcc/config/m68k/x-apollo68
@@ -2,8 +2,8 @@
# vasta@apollo.com says this is how to compile on an Apollo (SR10.x).
# Use a Berkeley environment.
-CC=cc -g -A nansi -A cpu,3000 -A runtype,bsd4.3 -A systype,any -DSHORT_ENUM_BUG
-OLDCC=cc -g -A nansi -A cpu,3000 -A runtype,bsd4.3 -A systype,any -DSHORT_ENUM_BUG
+CC=cc -g -A nansi -A cpu,3000 -A runtype,bsd4.3 -A systype,any
+OLDCC=cc -g -A nansi -A cpu,3000 -A runtype,bsd4.3 -A systype,any
# This used to redefine CFLAGS and LIBGCC2_CFLAGS to eliminate the unsupported
# -g flag from both macros. This gives an undebuggable stage1 compiler which
diff --git a/gcc/config/m68k/x-ccur b/gcc/config/m68k/x-ccur
index 0f94e9da2f0..3b0cad54b1d 100644
--- a/gcc/config/m68k/x-ccur
+++ b/gcc/config/m68k/x-ccur
@@ -1,3 +1,3 @@
# Specify the jobs library when building in the ATT universe.
CLIB = -ljobs
-X_CFLAGS = -O0 -DSHORT_ENUM_BUG -Dregister=
+X_CFLAGS = -O0 -Dregister=
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 598be36eba5..6f9f59b221f 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -130,6 +130,8 @@ extern int se_uns_arith_operand PARAMS ((rtx, enum machine_mode));
extern int se_arith_operand PARAMS ((rtx, enum machine_mode));
extern int se_nonmemory_operand PARAMS ((rtx, enum machine_mode));
extern int se_nonimmediate_operand PARAMS ((rtx, enum machine_mode));
+extern int mips_legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
+extern int mips_reg_mode_ok_for_base_p PARAMS ((rtx, enum machine_mode, int));
extern int extend_operator PARAMS ((rtx, enum machine_mode));
extern int highpart_shift_operator PARAMS ((rtx, enum machine_mode));
extern int m16_uimm3_b PARAMS ((rtx, enum machine_mode));
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index b7a7ffc8097..c19f35f57e6 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -91,8 +91,10 @@ static enum internal_test map_test_to_internal_test PARAMS ((enum rtx_code));
static int mips16_simple_memory_operand PARAMS ((rtx, rtx,
enum machine_mode));
static int m16_check_op PARAMS ((rtx, int, int, int));
-static void block_move_loop PARAMS ((rtx, rtx, int, int,
- rtx, rtx));
+static void block_move_loop PARAMS ((rtx, rtx,
+ unsigned int,
+ int,
+ rtx, rtx));
static void block_move_call PARAMS ((rtx, rtx, rtx));
static FILE *mips_make_temp_file PARAMS ((void));
static void save_restore_insns PARAMS ((int, rtx,
@@ -671,7 +673,8 @@ mips16_simple_memory_operand (reg, offset, mode)
rtx offset;
enum machine_mode mode;
{
- int size, off;
+ unsigned int size;
+ int off;
if (mode == BLKmode)
{
@@ -1208,6 +1211,136 @@ mips_check_split (address, mode)
return 0;
}
+
+/* This function is used to implement REG_MODE_OK_FOR_BASE_P. */
+
+int
+mips_reg_mode_ok_for_base_p (reg, mode, strict)
+ rtx reg;
+ enum machine_mode mode;
+ int strict;
+{
+ return (strict
+ ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
+ : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
+}
+
+/* This function is used to implement GO_IF_LEGITIMATE_ADDRESS. It
+ returns a nonzero value if XINSN is a legitimate address for a
+ memory operand of the indicated MODE. STRICT is non-zero if this
+ function is called during reload. */
+
+int
+mips_legitimate_address_p (mode, xinsn, strict)
+ enum machine_mode mode;
+ rtx xinsn;
+ int strict;
+{
+ if (TARGET_DEBUG_B_MODE)
+ {
+ GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
+ strict ? "" : "not ");
+ GO_DEBUG_RTX (xinsn);
+ }
+
+ /* Check for constant before stripping off SUBREG, so that we don't
+ accept (subreg (const_int)) which will fail to reload. */
+ if (CONSTANT_ADDRESS_P (xinsn)
+ && ! (mips_split_addresses && mips_check_split (xinsn, mode))
+ && (! TARGET_MIPS16 || mips16_constant (xinsn, mode, 1, 0)))
+ return 1;
+
+ while (GET_CODE (xinsn) == SUBREG)
+ xinsn = SUBREG_REG (xinsn);
+
+ /* The mips16 can only use the stack pointer as a base register when
+ loading SImode or DImode values. */
+ if (GET_CODE (xinsn) == REG
+ && mips_reg_mode_ok_for_base_p (xinsn, mode, strict))
+ return 1;
+
+ if (GET_CODE (xinsn) == LO_SUM && mips_split_addresses)
+ {
+ register rtx xlow0 = XEXP (xinsn, 0);
+ register rtx xlow1 = XEXP (xinsn, 1);
+
+ while (GET_CODE (xlow0) == SUBREG)
+ xlow0 = SUBREG_REG (xlow0);
+ if (GET_CODE (xlow0) == REG
+ && mips_reg_mode_ok_for_base_p (xlow0, mode, strict)
+ && mips_check_split (xlow1, mode))
+ return 1;
+ }
+
+ if (GET_CODE (xinsn) == PLUS)
+ {
+ register rtx xplus0 = XEXP (xinsn, 0);
+ register rtx xplus1 = XEXP (xinsn, 1);
+ register enum rtx_code code0;
+ register enum rtx_code code1;
+
+ while (GET_CODE (xplus0) == SUBREG)
+ xplus0 = SUBREG_REG (xplus0);
+ code0 = GET_CODE (xplus0);
+
+ while (GET_CODE (xplus1) == SUBREG)
+ xplus1 = SUBREG_REG (xplus1);
+ code1 = GET_CODE (xplus1);
+
+ /* The mips16 can only use the stack pointer as a base register
+ when loading SImode or DImode values. */
+ if (code0 == REG
+ && mips_reg_mode_ok_for_base_p (xplus0, mode, strict))
+ {
+ if (code1 == CONST_INT && SMALL_INT (xplus1))
+ return 1;
+
+ /* On the mips16, we represent GP relative offsets in RTL.
+ These are 16 bit signed values, and can serve as register
+ offsets. */
+ if (TARGET_MIPS16
+ && mips16_gp_offset_p (xplus1))
+ return 1;
+
+ /* For some code sequences, you actually get better code by
+ pretending that the MIPS supports an address mode of a
+ constant address + a register, even though the real
+ machine doesn't support it. This is because the
+ assembler can use $r1 to load just the high 16 bits, add
+ in the register, and fold the low 16 bits into the memory
+ reference, whereas the compiler generates a 4 instruction
+ sequence. On the other hand, CSE is not as effective.
+ It would be a win to generate the lui directly, but the
+ MIPS assembler does not have syntax to generate the
+ appropriate relocation. */
+
+ /* Also accept CONST_INT addresses here, so no else. */
+ /* Reject combining an embedded PIC text segment reference
+ with a register. That requires an additional
+ instruction. */
+ /* ??? Reject combining an address with a register for the MIPS
+ 64 bit ABI, because the SGI assembler can not handle this. */
+ if (!TARGET_DEBUG_A_MODE
+ && (mips_abi == ABI_32
+ || mips_abi == ABI_O64
+ || mips_abi == ABI_EABI)
+ && CONSTANT_ADDRESS_P (xplus1)
+ && ! mips_split_addresses
+ && (!TARGET_EMBEDDED_PIC
+ || code1 != CONST
+ || GET_CODE (XEXP (xplus1, 0)) != MINUS)
+ && !TARGET_MIPS16)
+ return 1;
+ }
+ }
+
+ if (TARGET_DEBUG_B_MODE)
+ GO_PRINTF ("Not a legitimate address\n");
+
+ /* The address was not legitimate. */
+ return 0;
+}
+
/* We need a lot of little routines to check constant values on the
mips16. These are used to figure out how long the instruction will
@@ -3033,7 +3166,7 @@ static void
block_move_loop (dest_reg, src_reg, bytes, align, orig_dest, orig_src)
rtx dest_reg; /* register holding destination address */
rtx src_reg; /* register holding source address */
- int bytes; /* # bytes to move */
+ unsigned int bytes; /* # bytes to move */
int align; /* alignment */
rtx orig_dest; /* original dest for change_address */
rtx orig_src; /* original source for making a reg note */
@@ -3145,14 +3278,14 @@ expand_block_move (operands)
rtx bytes_rtx = operands[2];
rtx align_rtx = operands[3];
int constp = GET_CODE (bytes_rtx) == CONST_INT;
- HOST_WIDE_INT bytes = constp ? INTVAL (bytes_rtx) : 0;
- int align = INTVAL (align_rtx);
+ unsigned HOST_WIDE_INT bytes = constp ? INTVAL (bytes_rtx) : 0;
+ unsigned int align = INTVAL (align_rtx);
rtx orig_src = operands[1];
rtx orig_dest = operands[0];
rtx src_reg;
rtx dest_reg;
- if (constp && bytes <= 0)
+ if (constp && bytes == 0)
return;
if (align > UNITS_PER_WORD)
@@ -3863,7 +3996,7 @@ function_arg (cum, mode, type, named)
unsigned int chunks;
HOST_WIDE_INT bitpos;
unsigned int regno;
- int i;
+ unsigned int i;
/* ??? If this is a packed structure, then the last hunk won't
be 64 bits. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index bc8c83e0732..6dd1a6ec908 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1295,20 +1295,20 @@ do { \
Note that this is not necessarily the width of data type `int';
if using 16-bit ints on a 68000, this would still be 32.
But on a machine with 16-bit registers, this would be 16. */
-#define BITS_PER_WORD ((unsigned int) (TARGET_64BIT ? 64 : 32))
+#define BITS_PER_WORD (TARGET_64BIT ? 64 : 32)
#define MAX_BITS_PER_WORD 64
/* Width of a word, in units (bytes). */
-#define UNITS_PER_WORD ((unsigned int) (TARGET_64BIT ? 8 : 4))
+#define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4)
#define MIN_UNITS_PER_WORD 4
/* For MIPS, width of a floating point register. */
-#define UNITS_PER_FPREG ((unsigned int) (TARGET_FLOAT64 ? 8 : 4))
+#define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4)
/* A C expression for the size in bits of the type `int' on the
target machine. If you don't define this, the default is one
word. */
-#define INT_TYPE_SIZE ((unsigned int) (TARGET_INT64 ? 64 : 32))
+#define INT_TYPE_SIZE (TARGET_INT64 ? 64 : 32)
#define MAX_INT_TYPE_SIZE 64
/* Tell the preprocessor the maximum size of wchar_t. */
@@ -1327,7 +1327,7 @@ do { \
/* A C expression for the size in bits of the type `long' on the
target machine. If you don't define this, the default is one
word. */
-#define LONG_TYPE_SIZE ((unsigned int) (TARGET_LONG64 ? 64 : 32))
+#define LONG_TYPE_SIZE (TARGET_LONG64 ? 64 : 32)
#define MAX_LONG_TYPE_SIZE 64
/* A C expression for the size in bits of the type `long long' on the
@@ -1359,14 +1359,14 @@ do { \
/* Width in bits of a pointer.
See also the macro `Pmode' defined below. */
#ifndef POINTER_SIZE
-#define POINTER_SIZE ((unsigned int) (Pmode == DImode ? 64 : 32))
+#define POINTER_SIZE (Pmode == DImode ? 64 : 32)
#endif
/* Allocation boundary (in *bits*) for storing pointers in memory. */
-#define POINTER_BOUNDARY ((unsigned int) (Pmode == DImode ? 64 : 32))
+#define POINTER_BOUNDARY (Pmode == DImode ? 64 : 32)
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
-#define PARM_BOUNDARY ((unsigned int) (TARGET_64BIT ? 64 : 32))
+#define PARM_BOUNDARY (TARGET_64BIT ? 64 : 32)
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
@@ -2725,21 +2725,15 @@ typedef struct mips_args {
need to be strict. */
#ifndef REG_OK_STRICT
-
-#define REG_OK_STRICT_P 0
-#define REG_OK_FOR_INDEX_P(X) 0
#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
- GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (X), (MODE))
-
+ mips_reg_mode_ok_for_base_p (X, MODE, 0)
#else
-
-#define REG_OK_STRICT_P 1
-#define REG_OK_FOR_INDEX_P(X) 0
#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
- REGNO_MODE_OK_FOR_BASE_P (REGNO (X), (MODE))
-
+ mips_reg_mode_ok_for_base_p (X, MODE, 1)
#endif
+#define REG_OK_FOR_INDEX_P(X) 0
+
/* Maximum number of registers that can appear in a valid memory address. */
@@ -2806,112 +2800,19 @@ typedef struct mips_args {
#define GO_DEBUG_RTX(x)
#endif
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- register rtx xinsn = (X); \
- \
- if (TARGET_DEBUG_B_MODE) \
- { \
- GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n", \
- (REG_OK_STRICT_P) ? "" : "not "); \
- GO_DEBUG_RTX (xinsn); \
- } \
- \
- /* Check for constant before stripping off SUBREG, so that we don't \
- accept (subreg (const_int)) which will fail to reload. */ \
- if (CONSTANT_ADDRESS_P (xinsn) \
- && ! (mips_split_addresses && mips_check_split (xinsn, MODE)) \
- && (! TARGET_MIPS16 || mips16_constant (xinsn, MODE, 1, 0))) \
- goto ADDR; \
- \
- while (GET_CODE (xinsn) == SUBREG) \
- xinsn = SUBREG_REG (xinsn); \
- \
- /* The mips16 can only use the stack pointer as a base register when \
- loading SImode or DImode values. */ \
- if (GET_CODE (xinsn) == REG && REG_MODE_OK_FOR_BASE_P (xinsn, MODE)) \
- goto ADDR; \
- \
- if (GET_CODE (xinsn) == LO_SUM && mips_split_addresses) \
- { \
- register rtx xlow0 = XEXP (xinsn, 0); \
- register rtx xlow1 = XEXP (xinsn, 1); \
- \
- while (GET_CODE (xlow0) == SUBREG) \
- xlow0 = SUBREG_REG (xlow0); \
- if (GET_CODE (xlow0) == REG \
- && REG_MODE_OK_FOR_BASE_P (xlow0, MODE) \
- && mips_check_split (xlow1, MODE)) \
- goto ADDR; \
- } \
- \
- if (GET_CODE (xinsn) == PLUS) \
- { \
- register rtx xplus0 = XEXP (xinsn, 0); \
- register rtx xplus1 = XEXP (xinsn, 1); \
- register enum rtx_code code0; \
- register enum rtx_code code1; \
- \
- while (GET_CODE (xplus0) == SUBREG) \
- xplus0 = SUBREG_REG (xplus0); \
- code0 = GET_CODE (xplus0); \
- \
- while (GET_CODE (xplus1) == SUBREG) \
- xplus1 = SUBREG_REG (xplus1); \
- code1 = GET_CODE (xplus1); \
- \
- /* The mips16 can only use the stack pointer as a base register \
- when loading SImode or DImode values. */ \
- if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, MODE)) \
- { \
- if (code1 == CONST_INT \
- && INTVAL (xplus1) >= -32768 \
- && INTVAL (xplus1) + GET_MODE_SIZE (MODE) - 1 <= 32767) \
- goto ADDR; \
- \
- /* On the mips16, we represent GP relative offsets in RTL. \
- These are 16 bit signed values, and can serve as register \
- offsets. */ \
- if (TARGET_MIPS16 \
- && mips16_gp_offset_p (xplus1)) \
- goto ADDR; \
- \
- /* For some code sequences, you actually get better code by \
- pretending that the MIPS supports an address mode of a \
- constant address + a register, even though the real \
- machine doesn't support it. This is because the \
- assembler can use $r1 to load just the high 16 bits, add \
- in the register, and fold the low 16 bits into the memory \
- reference, whereas the compiler generates a 4 instruction \
- sequence. On the other hand, CSE is not as effective. \
- It would be a win to generate the lui directly, but the \
- MIPS assembler does not have syntax to generate the \
- appropriate relocation. */ \
- \
- /* Also accept CONST_INT addresses here, so no else. */ \
- /* Reject combining an embedded PIC text segment reference \
- with a register. That requires an additional \
- instruction. */ \
- /* ??? Reject combining an address with a register for the MIPS \
- 64 bit ABI, because the SGI assembler can not handle this. */ \
- if (!TARGET_DEBUG_A_MODE \
- && (mips_abi == ABI_32 \
- || mips_abi == ABI_O64 \
- || mips_abi == ABI_EABI) \
- && CONSTANT_ADDRESS_P (xplus1) \
- && ! mips_split_addresses \
- && (!TARGET_EMBEDDED_PIC \
- || code1 != CONST \
- || GET_CODE (XEXP (xplus1, 0)) != MINUS) \
- && !TARGET_MIPS16) \
- goto ADDR; \
- } \
- } \
- \
- if (TARGET_DEBUG_B_MODE) \
- GO_PRINTF ("Not a legitimate address\n"); \
+#ifdef REG_OK_STRICT
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ \
+ if (mips_legitimate_address_p (MODE, X, 1)) \
+ goto ADDR; \
}
-
+#else
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ \
+ if (mips_legitimate_address_p (MODE, X, 0)) \
+ goto ADDR; \
+}
+#endif
/* A C expression that is 1 if the RTX X is a constant which is a
valid address. This is defined to be the same as `CONSTANT_P (X)',
diff --git a/gcc/config/mips/t-ecoff b/gcc/config/mips/t-ecoff
index 0bd0dd67d97..143126e2d49 100644
--- a/gcc/config/mips/t-ecoff
+++ b/gcc/config/mips/t-ecoff
@@ -70,7 +70,6 @@ INSTALL_LIBGCC = install-multilib
# cse.c (cost functions)
# insn-output.c (possible ifdef changes in tm.h)
# regclass.c (fixed/call used register changes)
-# cccp.c (new preprocessor macros, -v version #)
# explow.c (GO_IF_LEGITIMATE_ADDRESS)
# recog.c (GO_IF_LEGITIMATE_ADDRESS)
# reload.c (GO_IF_LEGITIMATE_ADDRESS)
@@ -85,7 +84,6 @@ varasm.o: $(CONFIG2_H)
cse.o: $(CONFIG2_H)
insn-output.o: $(CONFIG2_H)
regclass.o: $(CONFIG2_H)
-cccp.o: $(CONFIG2_H)
explow.o: $(CONFIG2_H)
recog.o: $(CONFIG2_H)
reload.o: $(CONFIG2_H)
diff --git a/gcc/config/mips/t-elf b/gcc/config/mips/t-elf
index 1ce60499e9e..410646e1a4a 100644
--- a/gcc/config/mips/t-elf
+++ b/gcc/config/mips/t-elf
@@ -74,7 +74,6 @@ INSTALL_LIBGCC = install-multilib
# cse.c (cost functions)
# insn-output.c (possible ifdef changes in tm.h)
# regclass.c (fixed/call used register changes)
-# cccp.c (new preprocessor macros, -v version #)
# explow.c (GO_IF_LEGITIMATE_ADDRESS)
# recog.c (GO_IF_LEGITIMATE_ADDRESS)
# reload.c (GO_IF_LEGITIMATE_ADDRESS)
@@ -89,7 +88,6 @@ varasm.o: $(CONFIG2_H)
cse.o: $(CONFIG2_H)
insn-output.o: $(CONFIG2_H)
regclass.o: $(CONFIG2_H)
-cccp.o: $(CONFIG2_H)
explow.o: $(CONFIG2_H)
recog.o: $(CONFIG2_H)
reload.o: $(CONFIG2_H)
diff --git a/gcc/config/mips/t-r3900 b/gcc/config/mips/t-r3900
index a7317665d08..f499da9b1ff 100644
--- a/gcc/config/mips/t-r3900
+++ b/gcc/config/mips/t-r3900
@@ -73,7 +73,6 @@ INSTALL_LIBGCC = install-multilib
# cse.c (cost functions)
# insn-output.c (possible ifdef changes in tm.h)
# regclass.c (fixed/call used register changes)
-# cccp.c (new preprocessor macros, -v version #)
# explow.c (GO_IF_LEGITIMATE_ADDRESS)
# recog.c (GO_IF_LEGITIMATE_ADDRESS)
# reload.c (GO_IF_LEGITIMATE_ADDRESS)
@@ -88,7 +87,6 @@ varasm.o: $(CONFIG2_H)
cse.o: $(CONFIG2_H)
insn-output.o: $(CONFIG2_H)
regclass.o: $(CONFIG2_H)
-cccp.o: $(CONFIG2_H)
explow.o: $(CONFIG2_H)
recog.o: $(CONFIG2_H)
reload.o: $(CONFIG2_H)
diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h
index 6ca396256cb..56aecc6eceb 100644
--- a/gcc/config/pdp11/pdp11.h
+++ b/gcc/config/pdp11/pdp11.h
@@ -147,11 +147,6 @@ extern int target_flags;
/* machine types from ansi */
#define SIZE_TYPE "unsigned int" /* definition of size_t */
-
-/* is used in cexp.y - we don't have target_flags there,
- so just give default definition
-
- hope it does not come back to haunt us! */
#define WCHAR_TYPE "int" /* or long int???? */
#define WCHAR_TYPE_SIZE 16
diff --git a/gcc/config/romp/xm-romp.h b/gcc/config/romp/xm-romp.h
index 37de6de8d38..acb5b8cecb1 100644
--- a/gcc/config/romp/xm-romp.h
+++ b/gcc/config/romp/xm-romp.h
@@ -47,8 +47,3 @@ Boston, MA 02111-1307, USA. */
#define bcopy(s,d,l) memcpy(d,s,l)
#define FUNCTION_CONVERSION_BUG
#endif
-
-/* We cannot allow cccp.o to contain a copy of BCOPY as this will
- cause multiple definitions since BLT and BCOPY share an object file
- in libc.a and the library references BLT. */
-#define BSTRING
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 557079695ec..a2b75121d3a 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -2504,7 +2504,7 @@ eligible_for_sibcall_delay (trial)
{
/* If the tail call is done using the call instruction,
we have to restore %o7 in the delay slot. */
- if (TARGET_ARCH64 && ! TARGET_CM_MEDLOW)
+ if ((TARGET_ARCH64 && ! TARGET_CM_MEDLOW) || flag_pic)
return 0;
/* %g1 is used to build the function address */
@@ -3735,7 +3735,7 @@ output_sibcall (insn, call_operand)
if (leaf_regs)
{
- int spare_slot = (TARGET_ARCH32 || TARGET_CM_MEDLOW);
+ int spare_slot = ((TARGET_ARCH32 || TARGET_CM_MEDLOW) && ! flag_pic);
int size = 0;
if ((actual_fsize || ! spare_slot) && delay_slot)
diff --git a/gcc/config/xm-linux.h b/gcc/config/xm-linux.h
index fc0848b5604..d3aec5f8b79 100644
--- a/gcc/config/xm-linux.h
+++ b/gcc/config/xm-linux.h
@@ -25,6 +25,3 @@ Boston, MA 02111-1307, USA. */
/* We do have one, but I'd like to use the one come with gcc since
we have been doing that for a long time with USG defined. H.J. */
#undef HAVE_STAB_H
-
-#undef BSTRING
-#define BSTRING
diff --git a/gcc/configure b/gcc/configure
index 07135e1cb2a..f1ef295ee3b 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -41,8 +41,6 @@ ac_help="$ac_help
install the user visible C preprocessor in DIR
(relative to PREFIX) as well as PREFIX/bin."
ac_help="$ac_help
- --disable-cpplib use the old isolated C preprocessor."
-ac_help="$ac_help
--enable-c-mbchar Enable multibyte characters for C and C++."
ac_help="$ac_help
--enable-threads enable thread usage for target GCC.
@@ -605,7 +603,7 @@ copy=cp
# - two terminals occur directly after each other
# - the path contains an element with a dot in it
echo $ac_n "checking LIBRARY_PATH variable""... $ac_c" 1>&6
-echo "configure:609: checking LIBRARY_PATH variable" >&5
+echo "configure:607: checking LIBRARY_PATH variable" >&5
case ${LIBRARY_PATH} in
[:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
library_path_setting="contains current directory"
@@ -630,7 +628,7 @@ fi
# - two terminals occur directly after each other
# - the path contains an element with a dot in it
echo $ac_n "checking GCC_EXEC_PREFIX variable""... $ac_c" 1>&6
-echo "configure:634: checking GCC_EXEC_PREFIX variable" >&5
+echo "configure:632: checking GCC_EXEC_PREFIX variable" >&5
case ${GCC_EXEC_PREFIX} in
[:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
gcc_exec_prefix_setting="contains current directory"
@@ -841,17 +839,6 @@ fi
fi
-# Use cpplib+cppmain for the preprocessor, but don't link it with the compiler.
-cpp_main=cppmain
-# Check whether --enable-cpplib or --disable-cpplib was given.
-if test "${enable_cpplib+set}" = set; then
- enableval="$enable_cpplib"
- if test x$enable_cpplib = xno; then
- cpp_main=cccp
-fi
-fi
-
-
# Enable Multibyte Characters for C/C++
# Check whether --enable-c-mbchar or --disable-c-mbchar was given.
@@ -968,7 +955,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:972: checking host system type" >&5
+echo "configure:959: checking host system type" >&5
host_alias=$host
case "$host_alias" in
@@ -989,7 +976,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:993: checking target system type" >&5
+echo "configure:980: checking target system type" >&5
target_alias=$target
case "$target_alias" in
@@ -1007,7 +994,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:1011: checking build system type" >&5
+echo "configure:998: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@@ -1034,7 +1021,7 @@ 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:1038: checking for $ac_word" >&5
+echo "configure:1025: 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
@@ -1064,7 +1051,7 @@ 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:1068: checking for $ac_word" >&5
+echo "configure:1055: 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
@@ -1115,7 +1102,7 @@ fi
# 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:1119: checking for $ac_word" >&5
+echo "configure:1106: 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
@@ -1147,7 +1134,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1151: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1138: 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.
@@ -1158,12 +1145,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
-#line 1162 "configure"
+#line 1149 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:1167: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1154: \"$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
@@ -1189,12 +1176,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:1193: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1180: 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:1198: checking whether we are using GNU C" >&5
+echo "configure:1185: 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
@@ -1203,7 +1190,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1207: \"$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:1194: \"$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
@@ -1222,7 +1209,7 @@ 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:1226: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1213: 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
@@ -1254,7 +1241,7 @@ else
fi
echo $ac_n "checking for long double""... $ac_c" 1>&6
-echo "configure:1258: checking for long double" >&5
+echo "configure:1245: checking for long double" >&5
if eval "test \"`echo '$''{'gcc_cv_c_long_double'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1262,7 +1249,7 @@ else
gcc_cv_c_long_double=yes
else
cat > conftest.$ac_ext <<EOF
-#line 1266 "configure"
+#line 1253 "configure"
#include "confdefs.h"
int main() {
@@ -1272,7 +1259,7 @@ long double foo = 0.0;
switch (0) case 0: case (sizeof(long double) >= sizeof(double)):;
; return 0; }
EOF
-if { (eval echo configure:1276: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1263: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_c_long_double=yes
else
@@ -1305,7 +1292,7 @@ fi
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1309: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:1296: 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
@@ -1333,7 +1320,7 @@ fi
echo $ac_n "checking whether a default assembler was specified""... $ac_c" 1>&6
-echo "configure:1337: checking whether a default assembler was specified" >&5
+echo "configure:1324: checking whether a default assembler was specified" >&5
if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
if test x"$gas_flag" = x"no"; then
echo "$ac_t""yes ($DEFAULT_ASSEMBLER)" 1>&6
@@ -1345,7 +1332,7 @@ else
fi
echo $ac_n "checking whether a default linker was specified""... $ac_c" 1>&6
-echo "configure:1349: checking whether a default linker was specified" >&5
+echo "configure:1336: checking whether a default linker was specified" >&5
if test x"${DEFAULT_LINKER+set}" = x"set"; then
if test x"$gnu_ld_flag" = x"no"; then
echo "$ac_t""yes ($DEFAULT_LINKER)" 1>&6
@@ -1362,7 +1349,7 @@ 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:1366: checking for $ac_word" >&5
+echo "configure:1353: 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
@@ -1394,7 +1381,7 @@ 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:1398: checking for $ac_word" >&5
+echo "configure:1385: 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
@@ -1428,7 +1415,7 @@ then
*) ac_lib=l ;;
esac
echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
-echo "configure:1432: checking for yywrap in -l$ac_lib" >&5
+echo "configure:1419: 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
@@ -1436,7 +1423,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-l$ac_lib $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1440 "configure"
+#line 1427 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1447,7 +1434,7 @@ int main() {
yywrap()
; return 0; }
EOF
-if { (eval echo configure:1451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1438: \"$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
@@ -1470,7 +1457,7 @@ fi
fi
echo $ac_n "checking whether ln works""... $ac_c" 1>&6
-echo "configure:1474: checking whether ln works" >&5
+echo "configure:1461: 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
@@ -1502,7 +1489,7 @@ else
fi
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1506: checking whether ln -s works" >&5
+echo "configure:1493: 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
@@ -1534,19 +1521,19 @@ else
fi
echo $ac_n "checking for volatile""... $ac_c" 1>&6
-echo "configure:1538: checking for volatile" >&5
+echo "configure:1525: 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 <<EOF
-#line 1543 "configure"
+#line 1530 "configure"
#include "confdefs.h"
int main() {
volatile int foo;
; return 0; }
EOF
-if { (eval echo configure:1550: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1537: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_c_volatile=yes
else
@@ -1569,7 +1556,7 @@ 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:1573: checking for $ac_word" >&5
+echo "configure:1560: 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
@@ -1601,7 +1588,7 @@ 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:1605: checking for $ac_word" >&5
+echo "configure:1592: 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
@@ -1642,7 +1629,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:1646: checking for a BSD compatible install" >&5
+echo "configure:1633: 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
@@ -1693,7 +1680,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:1697: checking how to run the C preprocessor" >&5
+echo "configure:1684: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -1708,13 +1695,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1712 "configure"
+#line 1699 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1718: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (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
:
@@ -1725,13 +1712,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1729 "configure"
+#line 1716 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1735: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1722: \"$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
:
@@ -1742,13 +1729,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1746 "configure"
+#line 1733 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1752: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (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
:
@@ -1773,12 +1760,12 @@ fi
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1777: checking for ANSI C header files" >&5
+echo "configure:1764: 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 <<EOF
-#line 1782 "configure"
+#line 1769 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1786,7 +1773,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1790: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1777: \"$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*
@@ -1803,7 +1790,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
-#line 1807 "configure"
+#line 1794 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1821,7 +1808,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
-#line 1825 "configure"
+#line 1812 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1842,7 +1829,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 1846 "configure"
+#line 1833 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1853,7 +1840,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-if { (eval echo configure:1857: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -1877,12 +1864,12 @@ EOF
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1881: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1868: 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 <<EOF
-#line 1886 "configure"
+#line 1873 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -1891,7 +1878,7 @@ int main() {
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1895: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1882: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
@@ -1912,12 +1899,12 @@ EOF
fi
echo $ac_n "checking whether string.h and strings.h may both be included""... $ac_c" 1>&6
-echo "configure:1916: checking whether string.h and strings.h may both be included" >&5
+echo "configure:1903: checking whether string.h and strings.h may both be included" >&5
if eval "test \"`echo '$''{'gcc_cv_header_string'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1921 "configure"
+#line 1908 "configure"
#include "confdefs.h"
#include <string.h>
#include <strings.h>
@@ -1925,7 +1912,7 @@ int main() {
; return 0; }
EOF
-if { (eval echo configure:1929: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1916: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_header_string=yes
else
@@ -1946,12 +1933,12 @@ EOF
fi
echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1950: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1937: checking for sys/wait.h that is POSIX.1 compatible" >&5
if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1955 "configure"
+#line 1942 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
@@ -1967,7 +1954,7 @@ wait (&s);
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
-if { (eval echo configure:1971: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1958: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
@@ -1994,17 +1981,17 @@ for ac_hdr in limits.h stddef.h string.h strings.h stdlib.h time.h \
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1998: checking for $ac_hdr" >&5
+echo "configure:1985: 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
-#line 2003 "configure"
+#line 1990 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2008: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1995: \"$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*
@@ -2034,17 +2021,17 @@ 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:2038: checking for thread.h" >&5
+echo "configure:2025: 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
-#line 2043 "configure"
+#line 2030 "configure"
#include "confdefs.h"
#include <thread.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2048: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2035: \"$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*
@@ -2068,17 +2055,17 @@ fi
ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for pthread.h""... $ac_c" 1>&6
-echo "configure:2072: checking for pthread.h" >&5
+echo "configure:2059: 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
-#line 2077 "configure"
+#line 2064 "configure"
#include "confdefs.h"
#include <pthread.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2082: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2069: \"$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*
@@ -2105,7 +2092,7 @@ fi
# Extract the first word of "gnatbind", so it can be a program name with args.
set dummy gnatbind; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2109: checking for $ac_word" >&5
+echo "configure:2096: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gnat'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2138,12 +2125,12 @@ fi
echo $ac_n "checking for preprocessor stringizing operator""... $ac_c" 1>&6
-echo "configure:2142: checking for preprocessor stringizing operator" >&5
+echo "configure:2129: checking for preprocessor stringizing operator" >&5
if eval "test \"`echo '$''{'ac_cv_c_stringize'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2147 "configure"
+#line 2134 "configure"
#include "confdefs.h"
#define x(y) #y
@@ -2176,12 +2163,12 @@ echo "$ac_t""${ac_cv_c_stringize}" 1>&6
# Use <inttypes.h> only if it exists,
# doesn't clash with <sys/types.h>, and declares intmax_t.
echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6
-echo "configure:2180: checking for inttypes.h" >&5
+echo "configure:2167: 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 <<EOF
-#line 2185 "configure"
+#line 2172 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <inttypes.h>
@@ -2189,7 +2176,7 @@ int main() {
intmax_t i = -1;
; return 0; }
EOF
-if { (eval echo configure:2193: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2180: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_header_inttypes_h=yes
else
@@ -2209,18 +2196,67 @@ EOF
fi
+#
+# Determine if enumerated bitfields are unsigned. ISO C says they can
+# be either signed or unsigned.
+#
+echo $ac_n "checking for unsigned enumerated bitfields""... $ac_c" 1>&6
+echo "configure:2205: checking for unsigned enumerated bitfields" >&5
+if eval "test \"`echo '$''{'gcc_cv_enum_bf_unsigned'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ gcc_cv_enum_bf_unsigned=yes
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2213 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+enum t { BLAH = 128 } ;
+struct s_t { enum t member : 8; } s ;
+int main(void)
+{
+ s.member = BLAH;
+ if (s.member < 0) exit(1);
+ exit(0);
+
+}
+EOF
+if { (eval echo configure:2226: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ gcc_cv_enum_bf_unsigned=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ gcc_cv_enum_bf_unsigned=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$gcc_cv_enum_bf_unsigned" 1>&6
+echo "$ac_t""$gcc_cv_enum_bf_unsigned" 1>&6
+if test $gcc_cv_enum_bf_unsigned = yes; then
+ cat >> confdefs.h <<\EOF
+#define ENUM_BITFIELDS_ARE_UNSIGNED 1
+EOF
+
+fi
+
for ac_func in strtoul bsearch putenv popen bcopy bzero bcmp \
index rindex strchr strrchr kill getrlimit setrlimit atoll atoq \
sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
fputs_unlocked getrusage valloc
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2219: checking for $ac_func" >&5
+echo "configure:2255: 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 <<EOF
-#line 2224 "configure"
+#line 2260 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2243,7 +2279,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2247: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2283: \"$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
@@ -2272,12 +2308,12 @@ done
#AC_CHECK_TYPE(wchar_t, unsigned int)
echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:2276: checking for vprintf" >&5
+echo "configure:2312: 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 <<EOF
-#line 2281 "configure"
+#line 2317 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vprintf(); below. */
@@ -2300,7 +2336,7 @@ vprintf();
; return 0; }
EOF
-if { (eval echo configure:2304: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2340: \"$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
@@ -2324,12 +2360,12 @@ fi
if test "$ac_cv_func_vprintf" != yes; then
echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:2328: checking for _doprnt" >&5
+echo "configure:2364: 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 <<EOF
-#line 2333 "configure"
+#line 2369 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char _doprnt(); below. */
@@ -2352,7 +2388,7 @@ _doprnt();
; return 0; }
EOF
-if { (eval echo configure:2356: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2392: \"$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
@@ -2388,7 +2424,7 @@ fi
echo $ac_n "checking whether the printf functions support %p""... $ac_c" 1>&6
-echo "configure:2392: checking whether the printf functions support %p" >&5
+echo "configure:2428: 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
@@ -2396,7 +2432,7 @@ else
gcc_cv_func_printf_ptr=no
else
cat > conftest.$ac_ext <<EOF
-#line 2400 "configure"
+#line 2436 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -2409,7 +2445,7 @@ main()
exit (p != q);
}
EOF
-if { (eval echo configure:2413: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2449: \"$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
@@ -2442,12 +2478,12 @@ case "${host}" in
;;
esac
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:2446: checking for pid_t" >&5
+echo "configure:2482: checking for pid_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2451 "configure"
+#line 2487 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -2476,17 +2512,17 @@ fi
ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
-echo "configure:2480: checking for vfork.h" >&5
+echo "configure:2516: checking for vfork.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
-#line 2485 "configure"
+#line 2521 "configure"
#include "confdefs.h"
#include <vfork.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2490: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2526: \"$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*
@@ -2511,18 +2547,18 @@ else
fi
echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-echo "configure:2515: checking for working vfork" >&5
+echo "configure:2551: checking for working vfork" >&5
if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
echo $ac_n "checking for vfork""... $ac_c" 1>&6
-echo "configure:2521: checking for vfork" >&5
+echo "configure:2557: checking for vfork" >&5
if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2526 "configure"
+#line 2562 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vfork(); below. */
@@ -2545,7 +2581,7 @@ vfork();
; return 0; }
EOF
-if { (eval echo configure:2549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2585: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_vfork=yes"
else
@@ -2567,7 +2603,7 @@ fi
ac_cv_func_vfork_works=$ac_cv_func_vfork
else
cat > conftest.$ac_ext <<EOF
-#line 2571 "configure"
+#line 2607 "configure"
#include "confdefs.h"
/* Thanks to Paul Eggert for this test. */
#include <stdio.h>
@@ -2662,7 +2698,7 @@ main() {
}
}
EOF
-if { (eval echo configure:2666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_vfork_works=yes
else
@@ -2688,17 +2724,17 @@ for ac_hdr in unistd.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2692: checking for $ac_hdr" >&5
+echo "configure:2728: 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
-#line 2697 "configure"
+#line 2733 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2738: \"$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*
@@ -2727,12 +2763,12 @@ done
for ac_func in getpagesize
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2731: checking for $ac_func" >&5
+echo "configure:2767: 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 <<EOF
-#line 2736 "configure"
+#line 2772 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2755,7 +2791,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2795: \"$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
@@ -2780,7 +2816,7 @@ fi
done
echo $ac_n "checking for working mmap from /dev/zero""... $ac_c" 1>&6
-echo "configure:2784: checking for working mmap from /dev/zero" >&5
+echo "configure:2820: checking for working mmap from /dev/zero" >&5
if eval "test \"`echo '$''{'ac_cv_func_mmap_anywhere'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2788,7 +2824,7 @@ else
ac_cv_func_mmap_anywhere=no
else
cat > conftest.$ac_ext <<EOF
-#line 2792 "configure"
+#line 2828 "configure"
#include "confdefs.h"
/* Test by Richard Henderson and Alexandre Oliva.
@@ -2860,7 +2896,7 @@ int main()
exit(0);
}
EOF
-if { (eval echo configure:2864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2900: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_mmap_anywhere=yes
else
@@ -2882,18 +2918,93 @@ EOF
fi
+echo $ac_n "checking for working mmap of a file""... $ac_c" 1>&6
+echo "configure:2923: checking for working mmap of a file" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_file'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # Create a file one thousand bytes long.
+for i in 1 2 3 4 5 6 7 8 9 0
+do for j in 1 2 3 4 5 6 7 8 9 0
+do echo $i $j xxxxx
+done
+done > conftestdata$$
+
+if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_file=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2938 "configure"
+#include "confdefs.h"
+
+/* Test by Zack Weinberg. Modified from MMAP_ANYWHERE test by
+ Richard Henderson and Alexandre Oliva.
+ Check whether read-only mmap of a plain file works. */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+int main()
+{
+ char *x;
+ int fd;
+ struct stat st;
+
+ fd = open("conftestdata$$", O_RDONLY);
+ if (fd < 0)
+ exit(1);
+
+ if (fstat (fd, &st))
+ exit(2);
+
+ x = (char*)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (x == (char *) -1)
+ exit(3);
+
+ if (x[0] != '1' || x[1] != ' ' || x[2] != '1' || x[3] != ' ')
+ exit(4);
+
+ if (munmap(x, st.st_size) < 0)
+ exit(5);
+
+ exit(0);
+}
+EOF
+if { (eval echo configure:2975: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_file=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_file=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_file" 1>&6
+if test $ac_cv_func_mmap_file = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP_FILE 1
+EOF
+
+fi
+
for ac_func in bcopy bzero bcmp \
index rindex getenv atol sbrk abort atof getcwd getwd \
strsignal putc_unlocked fputs_unlocked strstr environ
do
echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6
-echo "configure:2892: checking whether $ac_func must be declared" >&5
+echo "configure:3003: 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 <<EOF
-#line 2897 "configure"
+#line 3008 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -2930,7 +3041,7 @@ int main() {
char *(*pfn) = (char *(*)) $ac_func
; return 0; }
EOF
-if { (eval echo configure:2934: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3045: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "gcc_cv_decl_needed_$ac_func=no"
else
@@ -2959,12 +3070,12 @@ done
for ac_func in malloc realloc calloc free
do
echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6
-echo "configure:2963: checking whether $ac_func must be declared" >&5
+echo "configure:3074: 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 <<EOF
-#line 2968 "configure"
+#line 3079 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -3004,7 +3115,7 @@ int main() {
char *(*pfn) = (char *(*)) $ac_func
; return 0; }
EOF
-if { (eval echo configure:3008: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3119: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "gcc_cv_decl_needed_$ac_func=no"
else
@@ -3033,12 +3144,12 @@ done
for ac_func in getrlimit setrlimit getrusage
do
echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6
-echo "configure:3037: checking whether $ac_func must be declared" >&5
+echo "configure:3148: 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 <<EOF
-#line 3042 "configure"
+#line 3153 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -3079,7 +3190,7 @@ int main() {
char *(*pfn) = (char *(*)) $ac_func
; return 0; }
EOF
-if { (eval echo configure:3083: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3194: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "gcc_cv_decl_needed_$ac_func=no"
else
@@ -3107,12 +3218,12 @@ done
# mkdir takes a single argument on some systems.
echo $ac_n "checking if mkdir takes one argument""... $ac_c" 1>&6
-echo "configure:3111: checking if mkdir takes one argument" >&5
+echo "configure:3222: checking if mkdir takes one argument" >&5
if eval "test \"`echo '$''{'gcc_cv_mkdir_takes_one_arg'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3116 "configure"
+#line 3227 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -3129,7 +3240,7 @@ int main() {
mkdir ("foo", 0);
; return 0; }
EOF
-if { (eval echo configure:3133: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3244: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_mkdir_takes_one_arg=no
else
@@ -6573,7 +6684,7 @@ fi
echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6
-echo "configure:6577: checking for strerror in -lcposix" >&5
+echo "configure:6688: checking for strerror in -lcposix" >&5
ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -6581,7 +6692,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcposix $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6585 "configure"
+#line 6696 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6592,7 +6703,7 @@ int main() {
strerror()
; return 0; }
EOF
-if { (eval echo configure:6596: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6707: \"$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
@@ -6615,12 +6726,12 @@ fi
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:6619: checking for working const" >&5
+echo "configure:6730: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6624 "configure"
+#line 6735 "configure"
#include "confdefs.h"
int main() {
@@ -6669,7 +6780,7 @@ ccp = (char const *const *) p;
; return 0; }
EOF
-if { (eval echo configure:6673: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6784: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
@@ -6690,21 +6801,21 @@ EOF
fi
echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:6694: checking for inline" >&5
+echo "configure:6805: checking for inline" >&5
if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
cat > conftest.$ac_ext <<EOF
-#line 6701 "configure"
+#line 6812 "configure"
#include "confdefs.h"
int main() {
} $ac_kw foo() {
; return 0; }
EOF
-if { (eval echo configure:6708: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6819: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
@@ -6730,12 +6841,12 @@ EOF
esac
echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:6734: checking for off_t" >&5
+echo "configure:6845: checking for off_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6739 "configure"
+#line 6850 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -6763,12 +6874,12 @@ EOF
fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:6767: checking for size_t" >&5
+echo "configure:6878: checking for size_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6772 "configure"
+#line 6883 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -6798,19 +6909,19 @@ fi
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
# for constant arguments. Useless!
echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:6802: checking for working alloca.h" >&5
+echo "configure:6913: checking for working alloca.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6807 "configure"
+#line 6918 "configure"
#include "confdefs.h"
#include <alloca.h>
int main() {
char *p = alloca(2 * sizeof(int));
; return 0; }
EOF
-if { (eval echo configure:6814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6925: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_header_alloca_h=yes
else
@@ -6831,12 +6942,12 @@ EOF
fi
echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:6835: checking for alloca" >&5
+echo "configure:6946: checking for alloca" >&5
if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6840 "configure"
+#line 6951 "configure"
#include "confdefs.h"
#ifdef __GNUC__
@@ -6864,7 +6975,7 @@ int main() {
char *p = (char *) alloca(1);
; return 0; }
EOF
-if { (eval echo configure:6868: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6979: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_func_alloca_works=yes
else
@@ -6896,12 +7007,12 @@ EOF
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:6900: checking whether alloca needs Cray hooks" >&5
+echo "configure:7011: checking whether alloca needs Cray hooks" >&5
if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6905 "configure"
+#line 7016 "configure"
#include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2)
webecray
@@ -6926,12 +7037,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
if test $ac_cv_os_cray = yes; then
for ac_func in _getb67 GETB67 getb67; do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6930: checking for $ac_func" >&5
+echo "configure:7041: 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 <<EOF
-#line 6935 "configure"
+#line 7046 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6954,7 +7065,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7069: \"$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
@@ -6981,7 +7092,7 @@ done
fi
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:6985: checking stack direction for C alloca" >&5
+echo "configure:7096: checking stack direction for C alloca" >&5
if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -6989,7 +7100,7 @@ else
ac_cv_c_stack_direction=0
else
cat > conftest.$ac_ext <<EOF
-#line 6993 "configure"
+#line 7104 "configure"
#include "confdefs.h"
find_stack_direction ()
{
@@ -7008,7 +7119,7 @@ main ()
exit (find_stack_direction() < 0);
}
EOF
-if { (eval echo configure:7012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7123: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_stack_direction=1
else
@@ -7029,289 +7140,23 @@ EOF
fi
-for ac_hdr in unistd.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7037: 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
-#line 7042 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7047: \"$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"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-for ac_func in getpagesize
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7076: 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 <<EOF
-#line 7081 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:7104: \"$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
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:7129: checking for working mmap" >&5
-if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_func_mmap_fixed_mapped=no
-else
- cat > conftest.$ac_ext <<EOF
-#line 7137 "configure"
-#include "confdefs.h"
-
-/* Thanks to Mike Haertel and Jim Avera for this test.
- Here is a matrix of mmap possibilities:
- mmap private not fixed
- mmap private fixed at somewhere currently unmapped
- mmap private fixed at somewhere already mapped
- mmap shared not fixed
- mmap shared fixed at somewhere currently unmapped
- mmap shared fixed at somewhere already mapped
- For private mappings, we should verify that changes cannot be read()
- back from the file, nor mmap's back from the file at a different
- address. (There have been systems where private was not correctly
- implemented like the infamous i386 svr4.0, and systems where the
- VM page cache was not coherent with the filesystem buffer cache
- like early versions of FreeBSD and possibly contemporary NetBSD.)
- For shared mappings, we should conversely verify that changes get
- propogated back to all the places they're supposed to be.
-
- Grep wants private fixed already mapped.
- The main things grep needs to know about mmap are:
- * does it exist and is it safe to write into the mmap'd area
- * how to use it (BSD variants) */
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-
-/* This mess was copied from the GNU getpagesize.h. */
-#ifndef HAVE_GETPAGESIZE
-# ifdef HAVE_UNISTD_H
-# include <unistd.h>
-# endif
-
-/* Assume that all systems that can run configure have sys/param.h. */
-# ifndef HAVE_SYS_PARAM_H
-# define HAVE_SYS_PARAM_H 1
-# endif
-
-# ifdef _SC_PAGESIZE
-# define getpagesize() sysconf(_SC_PAGESIZE)
-# else /* no _SC_PAGESIZE */
-# ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-# ifdef EXEC_PAGESIZE
-# define getpagesize() EXEC_PAGESIZE
-# else /* no EXEC_PAGESIZE */
-# ifdef NBPG
-# define getpagesize() NBPG * CLSIZE
-# ifndef CLSIZE
-# define CLSIZE 1
-# endif /* no CLSIZE */
-# else /* no NBPG */
-# ifdef NBPC
-# define getpagesize() NBPC
-# else /* no NBPC */
-# ifdef PAGESIZE
-# define getpagesize() PAGESIZE
-# endif /* PAGESIZE */
-# endif /* no NBPC */
-# endif /* no NBPG */
-# endif /* no EXEC_PAGESIZE */
-# else /* no HAVE_SYS_PARAM_H */
-# define getpagesize() 8192 /* punt totally */
-# endif /* no HAVE_SYS_PARAM_H */
-# endif /* no _SC_PAGESIZE */
-
-#endif /* no HAVE_GETPAGESIZE */
-
-#ifdef __cplusplus
-extern "C" { void *malloc(unsigned); }
-#else
-char *malloc();
-#endif
-
-int
-main()
-{
- char *data, *data2, *data3;
- int i, pagesize;
- int fd;
-
- pagesize = getpagesize();
-
- /*
- * First, make a file with some known garbage in it.
- */
- data = malloc(pagesize);
- if (!data)
- exit(1);
- for (i = 0; i < pagesize; ++i)
- *(data + i) = rand();
- umask(0);
- fd = creat("conftestmmap", 0600);
- if (fd < 0)
- exit(1);
- if (write(fd, data, pagesize) != pagesize)
- exit(1);
- close(fd);
-
- /*
- * Next, try to mmap the file at a fixed address which
- * already has something else allocated at it. If we can,
- * also make sure that we see the same garbage.
- */
- fd = open("conftestmmap", O_RDWR);
- if (fd < 0)
- exit(1);
- data2 = malloc(2 * pagesize);
- if (!data2)
- exit(1);
- data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
- if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_FIXED, fd, 0L))
- exit(1);
- for (i = 0; i < pagesize; ++i)
- if (*(data + i) != *(data2 + i))
- exit(1);
-
- /*
- * Finally, make sure that changes to the mapped area
- * do not percolate back to the file as seen by read().
- * (This is a bug on some variants of i386 svr4.0.)
- */
- for (i = 0; i < pagesize; ++i)
- *(data2 + i) = *(data2 + i) + 1;
- data3 = malloc(pagesize);
- if (!data3)
- exit(1);
- if (read(fd, data3, pagesize) != pagesize)
- exit(1);
- for (i = 0; i < pagesize; ++i)
- if (*(data + i) != *(data3 + i))
- exit(1);
- close(fd);
- unlink("conftestmmap");
- exit(0);
-}
-
-EOF
-if { (eval echo configure:7277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
- ac_cv_func_mmap_fixed_mapped=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_func_mmap_fixed_mapped=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
-if test $ac_cv_func_mmap_fixed_mapped = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_MMAP 1
-EOF
-
-fi
-
-
+
for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
unistd.h sys/param.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7305: checking for $ac_hdr" >&5
+echo "configure:7150: 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
-#line 7310 "configure"
+#line 7155 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7315: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7160: \"$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*
@@ -7341,12 +7186,12 @@ done
strdup __argz_count __argz_stringify __argz_next
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7345: checking for $ac_func" >&5
+echo "configure:7190: 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 <<EOF
-#line 7350 "configure"
+#line 7195 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7369,7 +7214,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7218: \"$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
@@ -7398,12 +7243,12 @@ done
for ac_func in stpcpy
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7402: checking for $ac_func" >&5
+echo "configure:7247: 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 <<EOF
-#line 7407 "configure"
+#line 7252 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7426,7 +7271,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7430: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7275: \"$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
@@ -7460,19 +7305,19 @@ EOF
if test $ac_cv_header_locale_h = yes; then
echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
-echo "configure:7464: checking for LC_MESSAGES" >&5
+echo "configure:7309: checking for LC_MESSAGES" >&5
if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7469 "configure"
+#line 7314 "configure"
#include "confdefs.h"
#include <locale.h>
int main() {
return LC_MESSAGES
; return 0; }
EOF
-if { (eval echo configure:7476: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
am_cv_val_LC_MESSAGES=yes
else
@@ -7493,7 +7338,7 @@ EOF
fi
fi
echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
-echo "configure:7497: checking whether NLS is requested" >&5
+echo "configure:7342: checking whether NLS is requested" >&5
# Check whether --enable-nls or --disable-nls was given.
if test "${enable_nls+set}" = set; then
enableval="$enable_nls"
@@ -7513,7 +7358,7 @@ fi
EOF
echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
-echo "configure:7517: checking whether included gettext is requested" >&5
+echo "configure:7362: checking whether included gettext is requested" >&5
# Check whether --with-included-gettext or --without-included-gettext was given.
if test "${with_included_gettext+set}" = set; then
withval="$with_included_gettext"
@@ -7532,17 +7377,17 @@ fi
ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
-echo "configure:7536: checking for libintl.h" >&5
+echo "configure:7381: checking for libintl.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
-#line 7541 "configure"
+#line 7386 "configure"
#include "confdefs.h"
#include <libintl.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7546: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7391: \"$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*
@@ -7559,19 +7404,19 @@ fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
-echo "configure:7563: checking for gettext in libc" >&5
+echo "configure:7408: checking for gettext in libc" >&5
if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7568 "configure"
+#line 7413 "configure"
#include "confdefs.h"
#include <libintl.h>
int main() {
return (int) gettext ("")
; return 0; }
EOF
-if { (eval echo configure:7575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
gt_cv_func_gettext_libc=yes
else
@@ -7587,7 +7432,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
if test "$gt_cv_func_gettext_libc" != "yes"; then
echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
-echo "configure:7591: checking for bindtextdomain in -lintl" >&5
+echo "configure:7436: checking for bindtextdomain in -lintl" >&5
ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -7595,7 +7440,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lintl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7599 "configure"
+#line 7444 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7606,7 +7451,7 @@ int main() {
bindtextdomain()
; return 0; }
EOF
-if { (eval echo configure:7610: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7455: \"$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
@@ -7622,12 +7467,12 @@ fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
-echo "configure:7626: checking for gettext in libintl" >&5
+echo "configure:7471: checking for gettext in libintl" >&5
if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6
-echo "configure:7631: checking for gettext in -lintl" >&5
+echo "configure:7476: checking for gettext in -lintl" >&5
ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -7635,7 +7480,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lintl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7639 "configure"
+#line 7484 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7646,7 +7491,7 @@ int main() {
gettext()
; return 0; }
EOF
-if { (eval echo configure:7650: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7495: \"$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
@@ -7685,7 +7530,7 @@ EOF
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7689: checking for $ac_word" >&5
+echo "configure:7534: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7719,12 +7564,12 @@ fi
for ac_func in dcgettext
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7723: checking for $ac_func" >&5
+echo "configure:7568: 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 <<EOF
-#line 7728 "configure"
+#line 7573 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7747,7 +7592,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7751: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7596: \"$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
@@ -7774,7 +7619,7 @@ done
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7778: checking for $ac_word" >&5
+echo "configure:7623: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7810,7 +7655,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7814: checking for $ac_word" >&5
+echo "configure:7659: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7842,7 +7687,7 @@ else
fi
cat > conftest.$ac_ext <<EOF
-#line 7846 "configure"
+#line 7691 "configure"
#include "confdefs.h"
int main() {
@@ -7850,7 +7695,7 @@ extern int _nl_msg_cat_cntr;
return _nl_msg_cat_cntr
; return 0; }
EOF
-if { (eval echo configure:7854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
CATOBJEXT=.gmo
DATADIRNAME=share
@@ -7873,7 +7718,7 @@ fi
if test "$CATOBJEXT" = "NONE"; then
echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6
-echo "configure:7877: checking whether catgets can be used" >&5
+echo "configure:7722: checking whether catgets can be used" >&5
# Check whether --with-catgets or --without-catgets was given.
if test "${with_catgets+set}" = set; then
withval="$with_catgets"
@@ -7886,7 +7731,7 @@ fi
if test "$nls_cv_use_catgets" = "yes"; then
echo $ac_n "checking for main in -li""... $ac_c" 1>&6
-echo "configure:7890: checking for main in -li" >&5
+echo "configure:7735: checking for main in -li" >&5
ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -7894,14 +7739,14 @@ else
ac_save_LIBS="$LIBS"
LIBS="-li $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7898 "configure"
+#line 7743 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:7905: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7750: \"$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
@@ -7929,12 +7774,12 @@ else
fi
echo $ac_n "checking for catgets""... $ac_c" 1>&6
-echo "configure:7933: checking for catgets" >&5
+echo "configure:7778: checking for catgets" >&5
if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7938 "configure"
+#line 7783 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char catgets(); below. */
@@ -7957,7 +7802,7 @@ catgets();
; return 0; }
EOF
-if { (eval echo configure:7961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7806: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_catgets=yes"
else
@@ -7979,7 +7824,7 @@ EOF
# Extract the first word of "gencat", so it can be a program name with args.
set dummy gencat; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7983: checking for $ac_word" >&5
+echo "configure:7828: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8015,7 +7860,7 @@ fi
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8019: checking for $ac_word" >&5
+echo "configure:7864: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8052,7 +7897,7 @@ fi
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8056: checking for $ac_word" >&5
+echo "configure:7901: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8087,7 +7932,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8091: checking for $ac_word" >&5
+echo "configure:7936: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8145,7 +7990,7 @@ fi
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8149: checking for $ac_word" >&5
+echo "configure:7994: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8179,7 +8024,7 @@ fi
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8183: checking for $ac_word" >&5
+echo "configure:8028: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8215,7 +8060,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8219: checking for $ac_word" >&5
+echo "configure:8064: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8308,7 +8153,7 @@ fi
LINGUAS=
else
echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
-echo "configure:8312: checking for catalogs to be installed" >&5
+echo "configure:8157: checking for catalogs to be installed" >&5
NEW_LINGUAS=
for lang in ${LINGUAS=$ALL_LINGUAS}; do
case "$ALL_LINGUAS" in
@@ -8336,17 +8181,17 @@ echo "configure:8312: checking for catalogs to be installed" >&5
if test "$CATOBJEXT" = ".cat"; then
ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
-echo "configure:8340: checking for linux/version.h" >&5
+echo "configure:8185: checking for linux/version.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
-#line 8345 "configure"
+#line 8190 "configure"
#include "confdefs.h"
#include <linux/version.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8350: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8195: \"$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*
@@ -8421,7 +8266,7 @@ fi
echo $ac_n "checking whether windows registry support is requested""... $ac_c" 1>&6
-echo "configure:8425: checking whether windows registry support is requested" >&5
+echo "configure:8270: checking whether windows registry support is requested" >&5
if test x$enable_win32_registry != xno; then
cat >> confdefs.h <<\EOF
#define ENABLE_WIN32_REGISTRY 1
@@ -8450,7 +8295,7 @@ esac
if test x$enable_win32_registry != xno; then
echo $ac_n "checking registry key on windows hosts""... $ac_c" 1>&6
-echo "configure:8454: checking registry key on windows hosts" >&5
+echo "configure:8299: checking registry key on windows hosts" >&5
cat >> confdefs.h <<EOF
#define WIN32_REGISTRY_KEY "$gcc_cv_win32_registry_key"
EOF
@@ -8626,7 +8471,7 @@ fi
# Figure out what assembler alignment features are present.
echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6
-echo "configure:8630: checking assembler alignment features" >&5
+echo "configure:8475: 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
@@ -8747,7 +8592,7 @@ fi
echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6
echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6
-echo "configure:8751: checking assembler subsection support" >&5
+echo "configure:8596: checking assembler subsection support" >&5
gcc_cv_as_subsections=
if test x$gcc_cv_as != x; then
# Check if we have .subsection
@@ -8787,7 +8632,7 @@ fi
echo "$ac_t""$gcc_cv_as_subsections" 1>&6
echo $ac_n "checking assembler weak support""... $ac_c" 1>&6
-echo "configure:8791: checking assembler weak support" >&5
+echo "configure:8636: checking assembler weak support" >&5
gcc_cv_as_weak=
if test x$gcc_cv_as != x; then
# Check if we have .weak
@@ -8804,7 +8649,7 @@ fi
echo "$ac_t""$gcc_cv_as_weak" 1>&6
echo $ac_n "checking assembler hidden support""... $ac_c" 1>&6
-echo "configure:8808: checking assembler hidden support" >&5
+echo "configure:8653: checking assembler hidden support" >&5
gcc_cv_as_hidden=
if test x$gcc_cv_as != x; then
# Check if we have .hidden
@@ -8824,7 +8669,7 @@ echo "$ac_t""$gcc_cv_as_hidden" 1>&6
case "$target" in
sparc*-*-*)
echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
-echo "configure:8828: checking assembler .register pseudo-op support" >&5
+echo "configure:8673: checking assembler .register pseudo-op support" >&5
if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8854,7 +8699,7 @@ EOF
case "$tm_file" in
*64*)
echo $ac_n "checking for 64 bit support in assembler ($gcc_cv_as)""... $ac_c" 1>&6
-echo "configure:8858: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
+echo "configure:8703: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
if eval "test \"`echo '$''{'gcc_cv_as_flags64'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8899,7 +8744,7 @@ EOF
if test "x$gcc_cv_as_flags64" != xno; then
echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
-echo "configure:8903: checking for assembler offsetable %lo() support" >&5
+echo "configure:8748: checking for assembler offsetable %lo() support" >&5
if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8938,7 +8783,7 @@ EOF
i[34567]86-*-*)
echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
-echo "configure:8942: checking assembler instructions" >&5
+echo "configure:8787: checking assembler instructions" >&5
gcc_cv_as_instructions=
if test x$gcc_cv_as != x; then
set "filds fists" "filds mem; fists mem"
@@ -9064,7 +8909,7 @@ fi
# Build a new-libstdc++ system (ie libstdc++-v3)
echo $ac_n "checking for libstdc++ to install""... $ac_c" 1>&6
-echo "configure:9068: checking for libstdc++ to install" >&5
+echo "configure:8913: checking for libstdc++ to install" >&5
# Check whether --enable-libstdcxx-v3 or --disable-libstdcxx-v3 was given.
if test "${enable_libstdcxx_v3+set}" = set; then
enableval="$enable_libstdcxx_v3"
@@ -9336,7 +9181,6 @@ ${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xma
-
# Echo that links are built
if test x$host = x$target
then
@@ -9588,7 +9432,6 @@ s%@build_xm_file_list@%$build_xm_file_list%g
s%@cc_set_by_configure@%$cc_set_by_configure%g
s%@quoted_cc_set_by_configure@%$quoted_cc_set_by_configure%g
s%@cpp_install_dir@%$cpp_install_dir%g
-s%@cpp_main@%$cpp_main%g
s%@dep_host_xmake_file@%$dep_host_xmake_file%g
s%@dep_tmake_file@%$dep_tmake_file%g
s%@extra_c_flags@%$extra_c_flags%g
diff --git a/gcc/configure.in b/gcc/configure.in
index 403279cc7cd..8a82c87efab 100644
--- a/gcc/configure.in
+++ b/gcc/configure.in
@@ -217,14 +217,6 @@ elif test x$withval != xno; then
cpp_install_dir=$withval
fi])
-# Use cpplib+cppmain for the preprocessor, but don't link it with the compiler.
-cpp_main=cppmain
-AC_ARG_ENABLE(cpplib,
-[ --disable-cpplib use the old isolated C preprocessor.],
-if test x$enable_cpplib = xno; then
- cpp_main=cccp
-fi)
-
dnl Disable this for the moment; the library interface is changing.
dnl # Link cpplib into the compiler proper, for C/C++/ObjC.
dnl AC_ARG_ENABLE(c-cpplib,
@@ -234,7 +226,6 @@ dnl if test x$enable_c_cpplib != xno; then
dnl extra_c_objs="${extra_c_objs} libcpp.a"
dnl extra_cxx_objs="${extra_cxx_objs} ../libcpp.a"
dnl extra_c_flags="${extra_c_flags} -DUSE_CPPLIB=1"
-dnl cpp_main=cppmain
dnl fi)
# Enable Multibyte Characters for C/C++
@@ -377,6 +368,27 @@ if test $gcc_cv_header_inttypes_h = yes; then
AC_DEFINE(HAVE_INTTYPES_H)
fi
+#
+# Determine if enumerated bitfields are unsigned. ISO C says they can
+# be either signed or unsigned.
+#
+AC_CACHE_CHECK(for unsigned enumerated bitfields, gcc_cv_enum_bf_unsigned,
+[AC_TRY_RUN(#include <stdlib.h>
+enum t { BLAH = 128 } ;
+struct s_t { enum t member : 8; } s ;
+int main(void)
+{
+ s.member = BLAH;
+ if (s.member < 0) exit(1);
+ exit(0);
+
+}, gcc_cv_enum_bf_unsigned=yes, gcc_cv_enum_bf_unsigned=no, gcc_cv_enum_bf_unsigned=yes)])
+AC_MSG_RESULT($gcc_cv_enum_bf_unsigned)
+if test $gcc_cv_enum_bf_unsigned = yes; then
+ AC_DEFINE(ENUM_BITFIELDS_ARE_UNSIGNED, 1,
+ [Define if enumerated bitfields are treated as unsigned values.])
+fi
+
AC_CHECK_FUNCS(strtoul bsearch putenv popen bcopy bzero bcmp \
index rindex strchr strrchr kill getrlimit setrlimit atoll atoq \
sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
@@ -398,6 +410,7 @@ case "${host}" in
esac
AC_FUNC_VFORK
AC_FUNC_MMAP_ANYWHERE
+AC_FUNC_MMAP_FILE
GCC_NEED_DECLARATIONS(bcopy bzero bcmp \
index rindex getenv atol sbrk abort atof getcwd getwd \
@@ -4792,7 +4805,6 @@ AC_SUBST(build_xm_file_list)
AC_SUBST(cc_set_by_configure)
AC_SUBST(quoted_cc_set_by_configure)
AC_SUBST(cpp_install_dir)
-AC_SUBST(cpp_main)
AC_SUBST(dep_host_xmake_file)
AC_SUBST(dep_tmake_file)
AC_SUBST(extra_c_flags)
diff --git a/gcc/conflict.c b/gcc/conflict.c
index 667a18a672c..3113aa7d8ad 100644
--- a/gcc/conflict.c
+++ b/gcc/conflict.c
@@ -2,22 +2,22 @@
Copyright (C) 2000 Free Software Foundation, Inc.
Contributed by CodeSourcery, LLC
- This file is part of GNU CC.
+This file is part of GNU CC.
- GNU CC 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.
+GNU CC 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.
- GNU CC 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.
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
- the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* References:
@@ -27,7 +27,6 @@
#include "config.h"
#include "system.h"
-
#include "obstack.h"
#include "hashtab.h"
#include "rtl.h"
@@ -108,23 +107,18 @@ struct conflict_graph_def
/* The initial capacity (number of conflict arcs) for newly-created
conflict graphs. */
-#define INITIAL_ARC_CAPACITY (64)
+#define INITIAL_ARC_CAPACITY 64
/* Computes the hash value of the conflict graph arc connecting regs
- R1__ and R2__. R1__ is assumed to be smaller or equal to R2__. */
-#define CONFLICT_HASH_FN(r1__, r2__) ((r2__) * ((r2__) - 1) / 2 + (r1__))
-
-static unsigned arc_hash
- PARAMS ((const void *arcp));
-static int arc_eq
- PARAMS ((const void *arcp1, const void *arcp2));
-static int print_conflict
- PARAMS ((int reg1, int reg2, void *contextp));
-static void mark_reg
- PARAMS ((rtx reg, rtx setter, void *data));
-
-
+ R1 and R2. R1 is assumed to be smaller or equal to R2. */
+#define CONFLICT_HASH_FN(R1, R2) ((R2) * ((R2) - 1) / 2 + (R1))
+
+static unsigned arc_hash PARAMS ((const void *));
+static int arc_eq PARAMS ((const void *, const void *));
+static int print_conflict PARAMS ((int, int, void *));
+static void mark_reg PARAMS ((rtx, rtx, void *));
+
/* Callback function to compute the hash value of an arc. Uses
current_graph to locate the graph to which the arc belongs. */
@@ -133,6 +127,7 @@ arc_hash (arcp)
const void *arcp;
{
conflict_graph_arc arc = (conflict_graph_arc) arcp;
+
return CONFLICT_HASH_FN (arc->smaller, arc->larger);
}
@@ -146,6 +141,7 @@ arc_eq (arcp1, arcp2)
{
conflict_graph_arc arc1 = (conflict_graph_arc) arcp1;
conflict_graph_arc arc2 = (conflict_graph_arc) arcp2;
+
return arc1->smaller == arc2->smaller && arc1->larger == arc2->larger;
}
@@ -156,24 +152,23 @@ conflict_graph
conflict_graph_new (num_regs)
int num_regs;
{
- conflict_graph graph =
- (conflict_graph) xmalloc (sizeof (struct conflict_graph_def));
+ conflict_graph graph
+ = (conflict_graph) xmalloc (sizeof (struct conflict_graph_def));
graph->num_regs = num_regs;
/* Set up the hash table. No delete action is specified; memory
management of arcs is through the obstack. */
- graph->arc_hash_table =
- htab_create (INITIAL_ARC_CAPACITY, &arc_hash, &arc_eq, NULL);
+ graph->arc_hash_table
+ = htab_create (INITIAL_ARC_CAPACITY, &arc_hash, &arc_eq, NULL);
/* Create an obstack for allocating arcs. */
- obstack_init (&(graph->arc_obstack));
+ obstack_init (&graph->arc_obstack);
/* Create and zero the lookup table by register number. */
- graph->neighbor_heads = (conflict_graph_arc *)
- xmalloc (num_regs * sizeof (conflict_graph_arc));
- memset (graph->neighbor_heads, 0,
- num_regs * sizeof (conflict_graph_arc));
+ graph->neighbor_heads
+ = (conflict_graph_arc *) xmalloc (num_regs * sizeof (conflict_graph_arc));
+ memset (graph->neighbor_heads, 0, num_regs * sizeof (conflict_graph_arc));
return graph;
}
@@ -183,7 +178,7 @@ void
conflict_graph_delete (graph)
conflict_graph graph;
{
- obstack_free (&(graph->arc_obstack), NULL);
+ obstack_free (&graph->arc_obstack, NULL);
htab_delete (graph->arc_hash_table);
free (graph->neighbor_heads);
free (graph);
@@ -211,17 +206,18 @@ conflict_graph_add (graph, reg1, reg2)
dummy.smaller = smaller;
dummy.larger = larger;
- slot = htab_find_slot (graph->arc_hash_table, (void *) &dummy, 1);
+ slot = htab_find_slot (graph->arc_hash_table, (void *) &dummy, INSERT);
/* If the conflict is already there, do nothing. */
if (*slot != NULL)
return 0;
/* Allocate an arc. */
- arc = (conflict_graph_arc)
- obstack_alloc (&(graph->arc_obstack),
- sizeof (struct conflict_graph_arc_def));
-
+ arc
+ = (conflict_graph_arc)
+ obstack_alloc (&graph->arc_obstack,
+ sizeof (struct conflict_graph_arc_def));
+
/* Record the reg numbers. */
arc->smaller = smaller;
arc->larger = larger;
@@ -299,6 +295,7 @@ conflict_graph_merge_regs (graph, target, src)
while (arc != NULL)
{
int other = arc->smaller;
+
if (other == src)
other = arc->larger;
@@ -372,19 +369,22 @@ conflict_graph_print (graph, fp)
{
int reg;
struct print_context context;
- context.fp = fp;
+ context.fp = fp;
fprintf (fp, "Conflicts:\n");
+
/* Loop over registers supported in this graph. */
for (reg = 0; reg < graph->num_regs; ++reg)
{
context.reg = reg;
context.started = 0;
+
/* Scan the conflicts for reg, printing as we go. A label for
this line will be printed the first time a conflict is
printed for the reg; we won't start a new line if this reg
has no conflicts. */
conflict_graph_enum (graph, reg, &print_conflict, &context);
+
/* If this reg does have conflicts, end the line. */
if (context.started)
fputc ('\n', fp);
@@ -469,9 +469,7 @@ conflict_graph_compute (regs, p)
/* Walk the instruction stream backwards. */
head = bb->head;
insn = bb->end;
- for (insn = bb->end;
- insn != head;
- insn = PREV_INSN (insn))
+ for (insn = bb->end; insn != head; insn = PREV_INSN (insn))
{
int born_reg;
int live_reg;
@@ -497,20 +495,21 @@ conflict_graph_compute (regs, p)
/* For every reg born here, add a conflict with every other
reg live coming into this insn. */
- EXECUTE_IF_SET_IN_REG_SET (born,
- FIRST_PSEUDO_REGISTER,
- born_reg, {
- EXECUTE_IF_SET_IN_REG_SET (live,
- FIRST_PSEUDO_REGISTER,
- live_reg, {
- /* Build the conflict graph in terms of canonical
- regnos. */
- int b = partition_find (p, born_reg);
- int l = partition_find (p, live_reg);
- if (b != l)
- conflict_graph_add (graph, b, l);
- });
- });
+ EXECUTE_IF_SET_IN_REG_SET
+ (born, FIRST_PSEUDO_REGISTER, born_reg,
+ {
+ EXECUTE_IF_SET_IN_REG_SET
+ (live, FIRST_PSEUDO_REGISTER, live_reg,
+ {
+ /* Build the conflict graph in terms of canonical
+ regnos. */
+ int b = partition_find (p, born_reg);
+ int l = partition_find (p, live_reg);
+
+ if (b != l)
+ conflict_graph_add (graph, b, l);
+ });
+ });
/* Morgan's algorithm checks the operands of the insn
and adds them to the set of live regs. Instead, we
@@ -519,7 +518,8 @@ conflict_graph_compute (regs, p)
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
{
- int regno = REGNO (XEXP (link, 0));
+ unsigned int regno = REGNO (XEXP (link, 0));
+
if (REGNO_REG_SET_P (regs, regno))
SET_REGNO_REG_SET (live, regno);
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2c497256560..5022e8311cc 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,90 @@
+2000-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (init_rtti_processing): Set tinfo_var_id in new-abi.
+ (target_incomplete_p): New function.
+ (tinfo_base_init): Create comdat NTBS name variable.
+ (ptr_initializer): Add non_public parameter. Calculate it.
+ (ptmd_initializer): Likewise.
+ (synthesize_tinfo_var): Adjust. Emit incomplete class tinfo.
+ (create_real_tinfo_var): Add non_public parameter. Use it.
+ Push proxy into global namespace.
+ * inc/cxxabi.h (__pointer_type_info::incomplete_class_mask):
+ New enumeration.
+ * inc/typeinfo (type_info::before, type_info::operator==):
+ Compare __name addresses.
+
+ * tinfo2.cc: Remove new-abi builtins comment.
+
+2000-04-20 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck.c (build_x_function_call): Resolve an OFFSET_REF.
+
+ * call.c (joust): Exit early if we get the same function, too.
+
+ * decl2.c (key_method): Return NULL_TREE for template classes.
+ (import_export_class): Don't need to check for template classes.
+
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lex.c: Remove references to cccp.c.
+
+2000-04-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove const_memfunc and
+ volatile_memfunc. Add destructor_attr. Adjust dummy.
+ (DECL_DESTRUCTOR_P): Use destructor_attr.
+ (DECL_CONST_MEMFUNC_P): Reimplement.
+ (DECL_VOLATILE_MEMFUNC_P): Remove.
+ * class.c (finish_struct_methods): Use CLASSTYPE_DESTRUCTORS.
+ (overrides): Use DECL_DESTRUCTOR_P.
+ (check_for_override): Likewise.
+ * decl.c (start_function): Likewise.
+ * decl2.c (grokfclassfn): Likewise.
+ (check_classfn): Likewise.
+ (grok_function_init): Likewise.
+
+2000-04-17 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (grokfield): Issue error on illegal data member
+ declaration.
+
+Mon Apr 17 17:11:16 2000 Mark P Mitchell <mark@codesourcery.com>
+
+ * method.c (make_thunk): Set DECL_CONTEXT for a THUNK_DECL.
+
+2000-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable_entry): Don't build thunks for type-info
+ functions.
+
+2000-04-16 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (decls_match): Allow a redeclaration of a builtin to
+ specify args while the builtin did not.
+
+2000-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Add to documentation.
+ * cp-tree.h (flag_huge_objects): Declare.
+ * class.c (modify_vtable_entry): Tidy.
+ (update_vtable_entry_for_fn): Split out from dfs_modify_vtables.
+ Calculate delta appropriately for the new ABI.
+ (dfs_modify_vtables): Use it.
+ (modify_all_vtables): Fix thinko in code to add overriding copies
+ of functions to primary vtables.
+ (build_clone): Fix typo in comment.
+ (clone_function_decl): Correct order of destructors in vtable.
+ (build_vbase_offset_vtbl_entries): Adjust comment.
+ (dfs_vcall_offset_queue_p): Remove.
+ (dfs_build_vcall_offset_vtbl_entries): Update BV_VCALL_INDEX.
+ (build_vcall_offset_vtbl_entries): Juse use dfs_skip_vbases.
+ (build_vtable_entry): Correct check for pure virtual functions.
+ Don't declare flag_huge_objects.
+ * decl.c (flag_huge_objects): Remove declaration.
+ * method.c (make_thunk): Tweak mangling for vcall offset thunks.
+ Use int_size_in_bytes.
+ (emit_thunk): Handle vcall offset thunks.
+
Sat Apr 15 16:00:01 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* decl2.c (parse_time, varconst_time): Delete declarations.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 1ffbf60290e..085e264e485 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4923,8 +4923,9 @@ joust (cand1, cand2, warn)
return -1;
/* If we have two pseudo-candidates for conversions to the same type,
- arbitrarily pick one. */
- if (TYPE_P (cand1->fn) && cand1->fn == cand2->fn)
+ or two candidates for the same function, arbitrarily pick one. */
+ if (cand1->fn == cand2->fn
+ && (TYPE_P (cand1->fn) || DECL_P (cand1->fn)))
return 1;
/* a viable function F1
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index e89c733dcd4..b5d3f3e7b22 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -146,7 +146,6 @@ static void layout_virtual_bases PARAMS ((tree, varray_type *));
static tree dfs_set_offset_for_shared_vbases PARAMS ((tree, void *));
static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
static void build_vbase_offset_vtbl_entries PARAMS ((tree, vcall_offset_data *));
-static tree dfs_vcall_offset_queue_p PARAMS ((tree, void *));
static tree dfs_build_vcall_offset_vtbl_entries PARAMS ((tree, void *));
static void build_vcall_offset_vtbl_entries PARAMS ((tree, vcall_offset_data *));
static void layout_vtable_decl PARAMS ((tree, int));
@@ -977,9 +976,9 @@ make_new_vtable (t, binfo)
/* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO
(which is in the hierarchy dominated by T) list FNDECL as its
- BV_FN. DELTA is the required adjustment from the `this' pointer
- where the vtable entry appears to the `this' required when the
- function is actually called. */
+ BV_FN. DELTA is the required constant adjustment from the `this'
+ pointer where the vtable entry appears to the `this' required when
+ the function is actually called. */
static void
modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
@@ -989,15 +988,12 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
tree delta;
tree *virtuals;
{
- tree vcall_index;
tree v;
v = *virtuals;
- vcall_index = integer_zero_node;
if (fndecl != BV_FN (v)
- || !tree_int_cst_equal (delta, BV_DELTA (v))
- || !tree_int_cst_equal (vcall_index, BV_VCALL_INDEX (v)))
+ || !tree_int_cst_equal (delta, BV_DELTA (v)))
{
tree base_fndecl;
@@ -1015,7 +1011,7 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
base_fndecl = BV_FN (v);
BV_DELTA (v) = delta;
- BV_VCALL_INDEX (v) = vcall_index;
+ BV_VCALL_INDEX (v) = integer_zero_node;
BV_FN (v) = fndecl;
/* Now assign virtual dispatch information, if unset. We can
@@ -1087,7 +1083,8 @@ add_virtual_function (new_virtuals_p, overridden_virtuals_p,
/* We've already dealt with this function. */
return;
- new_virtual = build_tree_list (integer_zero_node, fndecl);
+ new_virtual = build_tree_list (NULL_TREE, fndecl);
+ BV_DELTA (new_virtual) = integer_zero_node;
BV_VCALL_INDEX (new_virtual) = integer_zero_node;
if (DECL_VINDEX (fndecl) == error_mark_node)
@@ -2158,7 +2155,7 @@ finish_struct_methods (t)
/* Clear out this flag. */
DECL_IN_AGGR_P (fn_fields) = 0;
- if (TYPE_HAS_DESTRUCTOR (t) && !TREE_VEC_ELT (method_vec, 1))
+ if (TYPE_HAS_DESTRUCTOR (t) && !CLASSTYPE_DESTRUCTORS (t))
/* We thought there was a destructor, but there wasn't. Some
parse errors cause this anomalous situation. */
TYPE_HAS_DESTRUCTOR (t) = 0;
@@ -2288,11 +2285,9 @@ overrides (fndecl, base_fndecl)
tree fndecl, base_fndecl;
{
/* Destructors have special names. */
- if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
- && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
+ if (DECL_DESTRUCTOR_P (base_fndecl) && DECL_DESTRUCTOR_P (fndecl))
return 1;
- if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
- || DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
+ if (DECL_DESTRUCTOR_P (base_fndecl) || DECL_DESTRUCTOR_P (fndecl))
return 0;
if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl))
{
@@ -2470,6 +2465,84 @@ dfs_find_base (binfo, data)
? binfo : NULL_TREE);
}
+/* Update a entry in the vtable for BINFO, which is in the hierarchy
+ dominated by T. FN has been overridden in BINFO; VIRTUALS points
+ to the corresponding position in the BINFO_VIRTUALS list. */
+
+static void
+update_vtable_entry_for_fn (t, binfo, fn, virtuals)
+ tree t;
+ tree binfo;
+ tree fn;
+ tree *virtuals;
+{
+ tree b;
+ tree overrider;
+ tree vindex;
+ tree delta;
+ HOST_WIDE_INT vindex_val;
+ HOST_WIDE_INT i;
+
+ /* Find the function which originally caused this vtable
+ entry to be present. */
+ vindex = DECL_VINDEX (fn);
+ b = dfs_walk (binfo, dfs_find_base, NULL, DECL_VIRTUAL_CONTEXT (fn));
+ fn = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (b)));
+ i = first_vfun_index (BINFO_TYPE (b));
+ vindex_val = tree_low_cst (vindex, 0);
+ while (i < vindex_val)
+ {
+ fn = TREE_CHAIN (fn);
+ ++i;
+ }
+ fn = BV_FN (fn);
+
+ /* Handle the case of a virtual function defined in BINFO itself. */
+ overrider = find_final_overrider (t, b, fn);
+ if (overrider == error_mark_node)
+ return;
+
+ /* Compute the constant adjustment to the `this' pointer. The
+ `this' pointer, when this function is called, will point at the
+ class whose vtable this is. */
+ delta = size_binop (PLUS_EXPR,
+ get_derived_offset (binfo,
+ DECL_VIRTUAL_CONTEXT (fn)),
+ BINFO_OFFSET (binfo));
+ if (flag_new_abi)
+ {
+ /* Under the new ABI, we only need to adjust as far as the
+ nearest virtual base. Then we use the vcall offset in the
+ virtual bases vtable. */
+ for (b = binfo; b; b = BINFO_INHERITANCE_CHAIN (b))
+ {
+ if (TREE_VIA_VIRTUAL (b))
+ break;
+ if (same_type_p (BINFO_TYPE (b),
+ BINFO_TYPE (TREE_VALUE (overrider))))
+ break;
+ }
+ }
+ else
+ b = NULL_TREE;
+
+ if (b && TREE_VIA_VIRTUAL (b))
+ /* The `this' pointer needs to be adjusted to the nearest virtual
+ base. */
+ delta = size_diffop (BINFO_OFFSET (b), delta);
+ else
+ /* The `this' pointer needs to be adjusted from pointing to
+ BINFO to pointing at the base where the final overrider
+ appears. */
+ delta = size_diffop (BINFO_OFFSET (TREE_VALUE (overrider)), delta);
+
+ modify_vtable_entry (t,
+ binfo,
+ TREE_PURPOSE (overrider),
+ delta,
+ virtuals);
+}
+
/* Called from modify_all_vtables via dfs_walk. */
static tree
@@ -2503,51 +2576,10 @@ dfs_modify_vtables (binfo, data)
virtuals;
virtuals = TREE_CHAIN (virtuals),
old_virtuals = TREE_CHAIN (old_virtuals))
- {
- tree b;
- tree fn;
- tree overrider;
- tree vindex;
- tree delta;
- HOST_WIDE_INT vindex_val;
- HOST_WIDE_INT i;
-
- /* Find the function which originally caused this vtable
- entry to be present. */
- fn = BV_FN (old_virtuals);
- vindex = DECL_VINDEX (fn);
- b = dfs_walk (binfo, dfs_find_base, NULL, DECL_VIRTUAL_CONTEXT (fn));
- fn = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (b)));
- i = first_vfun_index (BINFO_TYPE (b));
- vindex_val = tree_low_cst (vindex, 0);
- while (i < vindex_val)
- {
- fn = TREE_CHAIN (fn);
- ++i;
- }
- fn = BV_FN (fn);
-
- /* Handle the case of a virtual function defined in BINFO
- itself. */
- overrider = find_final_overrider (t, b, fn);
- if (overrider == error_mark_node)
- continue;
-
- /* The `this' pointer needs to be adjusted from pointing to
- BINFO to pointing at the base where the final overrider
- appears. */
- delta = size_binop (PLUS_EXPR,
- get_derived_offset (binfo,
- DECL_VIRTUAL_CONTEXT (fn)),
- BINFO_OFFSET (binfo));
- delta = size_diffop (BINFO_OFFSET (TREE_VALUE (overrider)), delta);
-
- modify_vtable_entry (t,
- binfo,
- TREE_PURPOSE (overrider),
- delta,
- &virtuals);
- }
+ update_vtable_entry_for_fn (t,
+ binfo,
+ BV_FN (old_virtuals),
+ &virtuals);
}
SET_BINFO_MARKED (binfo);
@@ -2591,8 +2623,8 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
{
tree fn = TREE_VALUE (*fnsp);
- if (BINFO_VIRTUALS (binfo)
- && !value_member (fn, BINFO_VIRTUALS (binfo)))
+ if (!BINFO_VIRTUALS (binfo)
+ || !value_member (fn, BINFO_VIRTUALS (binfo)))
{
/* Set the vtable index. */
set_vindex (t, fn, vfuns_p);
@@ -2710,8 +2742,7 @@ check_for_override (decl, ctype)
if (TYPE_POLYMORPHIC_P (BINFO_TYPE (base_binfo)))
{
tree tmp = get_matching_virtual
- (base_binfo, decl,
- DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
+ (base_binfo, decl, DECL_DESTRUCTOR_P (decl));
if (tmp && !found_overriden_fn)
{
@@ -3891,7 +3922,7 @@ build_clone (fn, name)
DECL_VINDEX (clone) = NULL_TREE;
}
- /* If there was an in-charge paramter, drop it from the function
+ /* If there was an in-charge parameter, drop it from the function
type. */
if (DECL_HAS_IN_CHARGE_PARM_P (clone))
{
@@ -3990,11 +4021,14 @@ clone_function_decl (fn, update_method_vec_p)
/* For each destructor, we need two variants: an in-charge
version, a not-in-charge version, and an in-charge deleting
- version. */
- clone = build_clone (fn, complete_dtor_identifier);
+ version. We clone the deleting version first because that
+ means it will go second on the TYPE_METHODS list -- and that
+ corresponds to the correct layout order in the virtual
+ function table. */
+ clone = build_clone (fn, deleting_dtor_identifier);
if (update_method_vec_p)
add_method (DECL_CONTEXT (clone), NULL, clone);
- clone = build_clone (fn, deleting_dtor_identifier);
+ clone = build_clone (fn, complete_dtor_identifier);
if (update_method_vec_p)
add_method (DECL_CONTEXT (clone), NULL, clone);
clone = build_clone (fn, base_dtor_identifier);
@@ -6637,9 +6671,9 @@ build_vbase_offset_vtbl_entries (binfo, vod)
vod->index, integer_one_node));
/* The initializer is the delta from BINFO to this virtual base.
- The vbase offsets go in reverse inheritance-graph order, and
- we are walking in inheritance graph order so these end up in
- the right order. */
+ The vbase offsets go in reverse inheritance-graph order, and
+ we are walking in inheritance graph order so these end up in
+ the right order. */
delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (binfo));
vod->inits = tree_cons (NULL_TREE,
fold (build1 (NOP_EXPR,
@@ -6652,58 +6686,69 @@ build_vbase_offset_vtbl_entries (binfo, vod)
/* Called from build_vcall_offset_vtbl_entries via dfs_walk. */
static tree
-dfs_vcall_offset_queue_p (binfo, data)
- tree binfo;
- void *data;
-{
- vcall_offset_data* vod = (vcall_offset_data *) data;
-
- return (binfo == vod->vbase) ? binfo : dfs_skip_vbases (binfo, NULL);
-}
-
-/* Called from build_vcall_offset_vtbl_entries via dfs_walk. */
-
-static tree
dfs_build_vcall_offset_vtbl_entries (binfo, data)
tree binfo;
void *data;
{
vcall_offset_data* vod;
- tree virtuals;
+ tree derived_virtuals;
+ tree base_virtuals;
tree binfo_inits;
+ tree non_primary_binfo;
tree b;
int i;
vod = (vcall_offset_data *) data;
binfo_inits = NULL_TREE;
-
+
+ /* We might be a primary base class. Go up the inheritance
+ hierarchy until we find the class of which we are a primary base:
+ it is the BINFO_VIRTUALS there that we need to consider. */
+ non_primary_binfo = binfo;
+ while (BINFO_PRIMARY_MARKED_P (non_primary_binfo))
+ non_primary_binfo = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
+
/* Skip virtuals that we have already handled in a primary base
class. */
- virtuals = BINFO_VIRTUALS (binfo);
+ base_virtuals = BINFO_VIRTUALS (binfo);
+ derived_virtuals = BINFO_VIRTUALS (non_primary_binfo);
b = BINFO_PRIMARY_BINFO (binfo);
if (b)
for (i = 0; i < CLASSTYPE_VSIZE (BINFO_TYPE (b)); ++i)
- virtuals = TREE_CHAIN (virtuals);
+ {
+ base_virtuals = TREE_CHAIN (base_virtuals);
+ derived_virtuals = TREE_CHAIN (derived_virtuals);
+ }
/* Make entries for the rest of the virtuals. */
- while (virtuals)
+ while (base_virtuals)
{
/* Figure out what function we're looking at. */
- tree fn = TREE_VALUE (virtuals);
+ tree fn = TREE_VALUE (derived_virtuals);
tree base = DECL_CONTEXT (fn);
/* The FN comes from BASE. So, we must caculate the adjustment
from the virtual base that derived from BINFO to BASE. */
tree base_binfo = get_binfo (base, vod->derived, /*protect=*/0);
+ /* Compute the vcall offset. */
binfo_inits
= tree_cons (NULL_TREE,
fold (build1 (NOP_EXPR, vtable_entry_type,
size_diffop (BINFO_OFFSET (base_binfo),
BINFO_OFFSET (vod->vbase)))),
binfo_inits);
+
+ /* Keep track of the vtable index where this vcall offset can be
+ found. */
+ BV_VCALL_INDEX (derived_virtuals) = vod->index;
+ /* The next vcall offset will be found at a more negative
+ offset. */
vod->index = fold (build (MINUS_EXPR, integer_type_node,
vod->index, integer_one_node));
- virtuals = TREE_CHAIN (virtuals);
+
+ /* Go to the next entries in the list. */
+ derived_virtuals = TREE_CHAIN (derived_virtuals);
+ base_virtuals = TREE_CHAIN (base_virtuals);
}
/* The offests are built up in reverse order, so we straighten them
@@ -6772,7 +6817,7 @@ build_vcall_offset_vtbl_entries (binfo, vod)
dfs_walk_real (binfo,
dfs_build_vcall_offset_vtbl_entries,
NULL,
- dfs_vcall_offset_queue_p,
+ dfs_skip_vbases,
vod);
vod->inits = chainon (vod->inits, inits);
}
@@ -6876,11 +6921,14 @@ build_vtable_entry (delta, vcall_index, entry)
{
HOST_WIDE_INT idelta;
HOST_WIDE_INT ivindex;
+ tree fn;
idelta = tree_low_cst (delta, 0);
ivindex = tree_low_cst (vcall_index, 0);
+ fn = TREE_OPERAND (entry, 0);
if ((idelta || ivindex)
- && ! DECL_PURE_VIRTUAL_P (TREE_OPERAND (entry, 0)))
+ && fn != abort_fndecl
+ && !DECL_TINFO_FN_P (fn))
{
entry = make_thunk (entry, idelta, ivindex);
entry = build1 (ADDR_EXPR, vtable_entry_type, entry);
@@ -6894,7 +6942,6 @@ build_vtable_entry (delta, vcall_index, entry)
}
else
{
- extern int flag_huge_objects;
tree elems = tree_cons (NULL_TREE, delta,
tree_cons (NULL_TREE, integer_zero_node,
build_tree_list (NULL_TREE, entry)));
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 4f826ab053c..30ebe45b450 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -161,8 +161,10 @@ DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0)
/* A thunk is a stub function.
A THUNK_DECL is an alternate entry point for an ordinary
- FUNCTION_DECL. It's job is to adjust the `this' poitner before
- transferring control to the FUNCTION_DECL.
+ FUNCTION_DECL. The address of the ordinary FUNCTION_DECL is given
+ by the DECL_INITIAL, which is always an ADDR_EXPR whose operand is
+ a FUNCTION_DECL. The job of the thunk is to adjust the `this'
+ pointer before transferring control to the FUNCTION_DECL.
A thunk may perform either, or both, of the following operations:
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a0e6d8a49bc..d419e26027f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -219,6 +219,11 @@ extern int flag_honor_std;
extern int flag_rtti;
+/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
+ objects. */
+
+extern int flag_huge_objects;
+
/* Nonzero if virtual base class offsets are stored in the virtual
function table. Zero if, instead, a pointer to the virtual base is
stored in the object itself. */
@@ -1767,7 +1772,7 @@ struct lang_type
struct A {};
struct B : public A { };
- struct C : virtual public B { void f(); };
+ struct C : virtual public B { void f(); int i; };
`A' is the primary base class for `B'. But, `B' is not a primary
base class for `C'. So, in the copy of `A' that appears in the
@@ -1856,12 +1861,12 @@ struct lang_decl_flags
unsigned operator_attr : 1;
unsigned constructor_attr : 1;
+ unsigned destructor_attr : 1;
unsigned friend_attr : 1;
unsigned static_function : 1;
- unsigned const_memfunc : 1;
- unsigned volatile_memfunc : 1;
unsigned pure_virtual : 1;
unsigned has_in_charge_parm_p : 1;
+ unsigned pretty_function_p : 1;
unsigned mutable_flag : 1;
unsigned deferred : 1;
@@ -1876,8 +1881,7 @@ struct lang_decl_flags
unsigned pending_inline_p : 1;
unsigned global_ctor_p : 1;
unsigned global_dtor_p : 1;
- unsigned pretty_function_p : 1;
- unsigned dummy : 2;
+ unsigned dummy : 3;
tree context;
@@ -1964,8 +1968,7 @@ struct lang_decl
/* There ought to be a better way to find out whether or not something is
a destructor. */
#define DECL_DESTRUCTOR_P(NODE) \
- (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (NODE)) \
- && DECL_LANGUAGE (NODE) == lang_cplusplus)
+ (DECL_LANG_SPECIFIC (NODE)->decl_flags.destructor_attr)
/* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the
specialized in-charge constructor, in-charge deleting constructor,
@@ -2073,11 +2076,10 @@ struct lang_decl
/* Nonzero for FUNCTION_DECL means that this member function
has `this' as const X *const. */
-#define DECL_CONST_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.const_memfunc)
-
-/* Nonzero for FUNCTION_DECL means that this member function
- has `this' as volatile X *const. */
-#define DECL_VOLATILE_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.volatile_memfunc)
+#define DECL_CONST_MEMFUNC_P(NODE) \
+ (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \
+ && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE \
+ (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
/* Nonzero for a DECL means that this member is a non-static member. */
#define DECL_NONSTATIC_MEMBER_P(NODE) \
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index cfb4618dc6e..f667fd52071 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -336,10 +336,6 @@ extern int flag_no_builtin;
extern int flag_no_nonansi_builtin;
-/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
- objects. */
-extern int flag_huge_objects;
-
/* Nonzero if we want to conserve space in the .o files. We do this
by putting uninitialized data and runtime initialized data into
.common instead of .data at the expense of not flagging multiple
@@ -2940,7 +2936,8 @@ decls_match (newdecl, olddecl)
if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
{
- if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c
+ if ((! strict_prototypes_lang_c || DECL_BUILT_IN (olddecl))
+ && DECL_LANGUAGE (olddecl) == lang_c
&& p2 == NULL_TREE)
{
types_match = self_promoting_args_p (p1);
@@ -13554,8 +13551,7 @@ start_function (declspecs, declarator, attrs, flags)
++function_depth;
- if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl1))
- && DECL_LANGUAGE (decl1) == lang_cplusplus)
+ if (DECL_DESTRUCTOR_P (decl1))
{
dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
DECL_CONTEXT (dtor_label) = current_function_decl;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 18d41aa9776..444b8a79468 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1037,6 +1037,7 @@ grokclassfn (ctype, function, flags, quals)
if (flags == DTOR_FLAG)
{
+ DECL_DESTRUCTOR_P (function) = 1;
DECL_ASSEMBLER_NAME (function) = build_destructor_name (ctype);
TYPE_HAS_DESTRUCTOR (ctype) = 1;
}
@@ -1389,7 +1390,7 @@ check_classfn (ctype, function)
&& DECL_CONSTRUCTOR_P (function))
goto got_it;
if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
- && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))
+ && DECL_DESTRUCTOR_P (function))
goto got_it;
while (++methods != end && *methods)
@@ -1410,7 +1411,7 @@ check_classfn (ctype, function)
we can't use this short-cut for them, either.
(It's not legal to declare arguments for a
destructor, but some people try.) */
- if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))
+ if (!DECL_DESTRUCTOR_P (function)
&& (DECL_ASSEMBLER_NAME (function)
!= DECL_NAME (function))
&& (DECL_ASSEMBLER_NAME (fndecl)
@@ -1572,7 +1573,23 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
|| TREE_CODE (TREE_OPERAND (declarator, 0)) == SCOPE_REF)
&& parmlist_is_exprlist (CALL_DECLARATOR_PARMS (declarator)))
{
- init = TREE_OPERAND (declarator, 1);
+ /* It's invalid to try to initialize a data member using a
+ functional notation, e.g.:
+
+ struct S {
+ static int i (3);
+ };
+
+ Explain that to the user. */
+ static int explained_p;
+
+ cp_error ("invalid data member initiailization");
+ if (!explained_p)
+ {
+ cp_error ("use `=' to initialize static data members");
+ explained_p = 1;
+ }
+
declarator = TREE_OPERAND (declarator, 0);
flags = 0;
}
@@ -1893,7 +1910,7 @@ grok_function_init (decl, init)
/* pure virtual destructors must be defined. */
/* pure virtual needs to be defined (as abort) only when put in
vtbl. For wellformed call, it should be itself. pr4737 */
- if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)))
+ if (!DECL_DESTRUCTOR_P (decl)))
{
/* Give this node rtl from `abort'. */
DECL_RTL (decl) = DECL_RTL (abort_fndecl);
@@ -2405,6 +2422,7 @@ key_method (type)
tree method;
if (TYPE_FOR_JAVA (type)
+ || CLASSTYPE_TEMPLATE_INSTANTIATION (type)
|| CLASSTYPE_INTERFACE_KNOWN (type))
return NULL_TREE;
@@ -2511,8 +2529,7 @@ import_export_class (ctype)
/* Base our import/export status on that of the first non-inline,
non-pure virtual function, if any. */
if (import_export == 0
- && TYPE_POLYMORPHIC_P (ctype)
- && ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
+ && TYPE_POLYMORPHIC_P (ctype))
{
tree method = key_method (ctype);
if (method)
diff --git a/gcc/cp/inc/cxxabi.h b/gcc/cp/inc/cxxabi.h
index 56c07d5cdd8..416b046e71a 100644
--- a/gcc/cp/inc/cxxabi.h
+++ b/gcc/cp/inc/cxxabi.h
@@ -68,7 +68,8 @@ public:
const_mask = 0x1,
volatile_mask = 0x2,
restrict_mask = 0x4,
- incomplete_mask = 0x8
+ incomplete_mask = 0x8,
+ incomplete_class_mask = 0x10
};
/* implementation defined member functions */
diff --git a/gcc/cp/inc/typeinfo b/gcc/cp/inc/typeinfo
index 632e4533d6a..8c5bbd839ad 100644
--- a/gcc/cp/inc/typeinfo
+++ b/gcc/cp/inc/typeinfo
@@ -56,14 +56,14 @@ public:
{ return !operator== (__arg); }
#else
- // In new abi we can rely on type_info's being unique,
+ // In new abi we can rely on type_info's NTBS being unique,
// and therefore address comparisons are sufficient.
bool before (const type_info& __arg) const
- { return this < &__arg; }
+ { return __name < __arg.__name; }
const char* name () const
{ return __name; }
bool operator== (const type_info& __arg) const
- { return &__arg == this; }
+ { return __name == __arg.__name; }
bool operator!= (const type_info& __arg) const
{ return !operator== (__arg); }
#endif
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index b25693170cd..da03c742852 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -2302,7 +2302,7 @@ check_newline ()
}
else if (!strcmp (name, "ident"))
{
- /* #ident. The pedantic warning is now in cccp.c. */
+ /* #ident. The pedantic warning is now in cpp. */
/* Here we have just seen `#ident '.
A string constant should follow. */
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index ecc7dc03fc5..31b02be8a18 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -2036,12 +2036,12 @@ make_thunk (function, delta, vcall_index)
else
icat (-delta);
OB_PUTC ('_');
- OB_PUTID (DECL_ASSEMBLER_NAME (func_decl));
if (vcall_index)
{
- OB_PUTC ('_');
icat (vcall_index);
+ OB_PUTC ('_');
}
+ OB_PUTID (DECL_ASSEMBLER_NAME (func_decl));
OB_FINISH ();
thunk_id = get_identifier (obstack_base (&scratch_obstack));
@@ -2062,9 +2062,10 @@ make_thunk (function, delta, vcall_index)
DECL_INITIAL (thunk) = function;
THUNK_DELTA (thunk) = delta;
THUNK_VCALL_OFFSET (thunk)
- = vcall_index * TREE_INT_CST_LOW (TYPE_SIZE (vtable_entry_type));
+ = vcall_index * int_size_in_bytes (vtable_entry_type);
DECL_EXTERNAL (thunk) = 1;
DECL_ARTIFICIAL (thunk) = 1;
+ DECL_CONTEXT (thunk) = DECL_CONTEXT (func_decl);
/* So that finish_file can write out any thunks that need to be: */
pushdecl_top_level (thunk);
}
@@ -2077,8 +2078,10 @@ void
emit_thunk (thunk_fndecl)
tree thunk_fndecl;
{
- tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0);
+ tree fnaddr = DECL_INITIAL (thunk_fndecl);
+ tree function = TREE_OPERAND (fnaddr, 0);
int delta = THUNK_DELTA (thunk_fndecl);
+ int vcall_offset = THUNK_VCALL_OFFSET (thunk_fndecl);
if (TREE_ASM_WRITTEN (thunk_fndecl))
return;
@@ -2094,7 +2097,7 @@ emit_thunk (thunk_fndecl)
TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL);
#ifdef ASM_OUTPUT_MI_THUNK
- if (!flag_syntax_only)
+ if (!flag_syntax_only && vcall_offset == 0)
{
const char *fnname;
current_function_decl = thunk_fndecl;
@@ -2112,7 +2115,8 @@ emit_thunk (thunk_fndecl)
current_function_decl = 0;
cfun = 0;
}
-#else /* ASM_OUTPUT_MI_THUNK */
+ else
+#endif /* ASM_OUTPUT_MI_THUNK */
{
/* If we don't have the necessary macro for efficient thunks, generate a
thunk function that just makes a call to the real function.
@@ -2140,16 +2144,44 @@ emit_thunk (thunk_fndecl)
copy_lang_decl (thunk_fndecl);
DECL_INTERFACE_KNOWN (thunk_fndecl) = 1;
DECL_NOT_REALLY_EXTERN (thunk_fndecl) = 1;
+ DECL_SAVED_FUNCTION_DATA (thunk_fndecl) = NULL;
- start_function (NULL_TREE, thunk_fndecl, NULL_TREE,
- SF_DEFAULT | SF_PRE_PARSED);
+ push_to_top_level ();
+ start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
store_parm_decls ();
current_function_is_thunk = 1;
- /* Build up the call to the real function. */
- t = build_int_2 (delta, -1 * (delta < 0));
+ /* Adjust the this pointer by the constant. */
+ t = ssize_int (delta);
TREE_TYPE (t) = signed_type (sizetype);
t = fold (build (PLUS_EXPR, TREE_TYPE (a), a, t));
+ /* If there's a vcall offset, look up that value in the vtable and
+ adjust the `this' pointer again. */
+ if (vcall_offset != 0)
+ {
+ tree orig_this;
+
+ t = save_expr (t);
+ orig_this = t;
+ /* The vptr is always at offset zero in the object. */
+ t = build1 (NOP_EXPR,
+ build_pointer_type (build_pointer_type
+ (vtable_entry_type)),
+ t);
+ /* Form the vtable address. */
+ t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
+ /* Find the entry with the vcall offset. */
+ t = build (PLUS_EXPR, TREE_TYPE (t), t, ssize_int (vcall_offset));
+ /* Calculate the offset itself. */
+ t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
+ /* Adjust the `this' pointer. */
+ t = fold (build (PLUS_EXPR,
+ TREE_TYPE (orig_this),
+ orig_this,
+ t));
+ }
+
+ /* Build up the call to the real function. */
t = tree_cons (NULL_TREE, t, NULL_TREE);
for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
t = tree_cons (NULL_TREE, a, t);
@@ -2157,13 +2189,21 @@ emit_thunk (thunk_fndecl)
t = build_call (function, t);
finish_return_stmt (t);
+ /* The back-end expects DECL_INITIAL to contain a BLOCK, so we
+ clear this here. */
+ DECL_INITIAL (thunk_fndecl) = NULL_TREE;
+ DECL_INITIAL (thunk_fndecl) = make_node (BLOCK);
+ BLOCK_VARS (DECL_INITIAL (thunk_fndecl))
+ = DECL_ARGUMENTS (thunk_fndecl);
expand_body (finish_function (0));
+ /* Restore the DECL_INITIAL for the THUNK_DECL. */
+ DECL_INITIAL (thunk_fndecl) = fnaddr;
+ pop_from_top_level ();
/* Don't let the backend defer this function. */
if (DECL_DEFER_OUTPUT (thunk_fndecl))
output_inline_function (thunk_fndecl);
}
-#endif /* ASM_OUTPUT_MI_THUNK */
TREE_SET_CODE (thunk_fndecl, THUNK_DECL);
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index caf84c8d516..a3d059d3070 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8904,7 +8904,7 @@ get_class_bindings (tparms, parms, args)
instantiation, or if there is no corresponding instantiation, the
template itself. EXPLICIT_ARGS is any template arguments explicity
mentioned in a template-id. If there is no most specialized
- tempalte, error_mark_node is returned. If there are no templates
+ template, error_mark_node is returned. If there are no templates
at all, NULL_TREE is returned. */
tree
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 0ad29d553c7..b16faf7358e 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -62,16 +62,17 @@ static tree throw_bad_typeid PARAMS((void));
static tree get_tinfo_decl_dynamic PARAMS((tree));
static tree tinfo_from_decl PARAMS((tree));
static int qualifier_flags PARAMS((tree));
+static int target_incomplete_p PARAMS((tree));
static tree tinfo_base_init PARAMS((tree, tree));
static tree generic_initializer PARAMS((tree, tree));
-static tree ptr_initializer PARAMS((tree, tree));
-static tree ptmd_initializer PARAMS((tree, tree));
+static tree ptr_initializer PARAMS((tree, tree, int *));
+static tree ptmd_initializer PARAMS((tree, tree, int *));
static tree dfs_class_hint_mark PARAMS ((tree, void *));
static tree dfs_class_hint_unmark PARAMS ((tree, void *));
static int class_hint_flags PARAMS((tree));
static tree class_initializer PARAMS((tree, tree, tree));
static tree synthesize_tinfo_var PARAMS((tree, tree));
-static tree create_real_tinfo_var PARAMS((tree, tree, tree));
+static tree create_real_tinfo_var PARAMS((tree, tree, tree, int));
static tree create_pseudo_type_info PARAMS((const char *, int, ...));
static tree get_vmi_pseudo_type_info PARAMS((int));
static void create_tinfo_types PARAMS((void));
@@ -95,14 +96,16 @@ init_rtti_processing ()
(build_qualified_type
(type_info_type_node, TYPE_QUAL_CONST)),
void_list_node);
+ tinfo_var_id = get_identifier ("__ti");
}
else
{
+ /* FIXME: These identifier prefixes are not set in stone yet. */
tinfo_decl_id = get_identifier ("__ti");
+ tinfo_var_id = get_identifier ("__tn");
tinfo_decl_type = build_qualified_type
(type_info_type_node, TYPE_QUAL_CONST);
}
- tinfo_var_id = get_identifier ("__ti");
}
/* Given a pointer to an object with at least one virtual table
@@ -1296,16 +1299,61 @@ qualifier_flags (type)
return flags;
}
+/* Return non-zero, if the pointer chain TYPE ends at an incomplete type, or
+ contains a pointer to member of an incomplete class. */
+
+static int
+target_incomplete_p (type)
+ tree type;
+{
+ while (TREE_CODE (type) == POINTER_TYPE)
+ if (TYPE_PTRMEM_P (type))
+ {
+ if (!COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)))
+ return 1;
+ type = TYPE_PTRMEM_POINTED_TO_TYPE (type);
+ }
+ else
+ type = TREE_TYPE (type);
+ if (!COMPLETE_OR_VOID_TYPE_P (type))
+ return 1;
+
+ return 0;
+}
+
/* Return a CONSTRUCTOR for the common part of the type_info objects. This
- is the vtable pointer and NTBS name. */
+ is the vtable pointer and NTBS name. The NTBS name is emitted as a
+ comdat const char array, so it becomes a unique key for the type. Generate
+ and emit that VAR_DECL here. (We can't always emit the type_info itself
+ as comdat, because of pointers to incomplete.) */
static tree
tinfo_base_init (desc, target)
tree desc;
tree target;
{
- tree name_string = tinfo_name (target);
tree init = NULL_TREE;
+ tree name_decl;
+
+ {
+ /* Generate the NTBS array variable. */
+ tree name_name = build_overload_with_type (tinfo_var_id, target);
+ tree name_type = build_cplus_array_type
+ (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
+ NULL_TREE);
+ tree name_string = tinfo_name (target);
+ name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
+
+ DECL_ARTIFICIAL (name_decl) = 1;
+ TREE_READONLY (name_decl) = 1;
+ TREE_STATIC (name_decl) = 1;
+ DECL_EXTERNAL (name_decl) = 0;
+ TREE_PUBLIC (name_decl) = 1;
+ comdat_linkage (name_decl);
+ DECL_ASSEMBLER_NAME (name_decl) = DECL_NAME (name_decl);
+ DECL_INITIAL (name_decl) = name_string;
+ cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
+ }
if (TINFO_VTABLE_DECL (desc))
{
@@ -1313,7 +1361,7 @@ tinfo_base_init (desc, target)
init = tree_cons (NULL_TREE, vtbl_ptr, init);
}
- init = tree_cons (NULL_TREE, decay_conversion (name_string), init);
+ init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
@@ -1343,14 +1391,21 @@ generic_initializer (desc, target)
which adds target type and qualifier flags members to the type_info base. */
static tree
-ptr_initializer (desc, target)
+ptr_initializer (desc, target, non_public_ptr)
tree desc;
tree target;
+ int *non_public_ptr;
{
tree init = tinfo_base_init (desc, target);
tree to = TREE_TYPE (target);
int flags = qualifier_flags (to);
+ int incomplete = target_incomplete_p (to);
+ if (incomplete)
+ {
+ flags |= 8;
+ *non_public_ptr = 1;
+ }
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
init = tree_cons (NULL_TREE,
build_unary_op (ADDR_EXPR,
@@ -1364,18 +1419,28 @@ ptr_initializer (desc, target)
/* Return the CONSTRUCTOR expr for a type_info of pointer to member data TYPE.
DESC provides information about the particular type_info derivation,
- which adds target type and qualifier flags members to the type_info base. */
+ which adds class, target type and qualifier flags members to the type_info
+ base. */
static tree
-ptmd_initializer (desc, target)
+ptmd_initializer (desc, target, non_public_ptr)
tree desc;
tree target;
+ int *non_public_ptr;
{
tree init = tinfo_base_init (desc, target);
tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target);
tree klass = TYPE_PTRMEM_CLASS_TYPE (target);
int flags = qualifier_flags (to);
+ int incomplete = target_incomplete_p (to);
+ if (incomplete)
+ {
+ flags |= 0x8;
+ *non_public_ptr = 1;
+ }
+ if (!COMPLETE_TYPE_P (klass))
+ flags |= 0x10;
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
init = tree_cons (NULL_TREE,
build_unary_op (ADDR_EXPR,
@@ -1489,6 +1554,7 @@ synthesize_tinfo_var (target_type, real_name)
{
tree var_init = NULL_TREE;
tree var_type = NULL_TREE;
+ int non_public = 0;
my_friendly_assert (new_abi_rtti_p (), 20000118);
@@ -1498,7 +1564,7 @@ synthesize_tinfo_var (target_type, real_name)
if (TYPE_PTRMEM_P (target_type))
{
var_type = ptmd_desc_type_node;
- var_init = ptmd_initializer (var_type, target_type);
+ var_init = ptmd_initializer (var_type, target_type, &non_public);
}
else
{
@@ -1513,7 +1579,7 @@ synthesize_tinfo_var (target_type, real_name)
/* These are in the runtime. */
return NULL_TREE;
var_type = ptr_desc_type_node;
- var_init = ptr_initializer (var_type, target_type);
+ var_init = ptr_initializer (var_type, target_type, &non_public);
}
break;
case ENUMERAL_TYPE:
@@ -1532,8 +1598,10 @@ synthesize_tinfo_var (target_type, real_name)
case RECORD_TYPE:
if (!COMPLETE_TYPE_P (target_type))
{
- /* FIXME: incomplete type. Awaiting specification. */
- return NULL_TREE;
+ /* Emit a non-public class_type_info. */
+ non_public = 1;
+ var_type = class_desc_type_node;
+ var_init = class_initializer (var_type, target_type, NULL_TREE);
}
else if (!CLASSTYPE_N_BASECLASSES (target_type))
{
@@ -1620,32 +1688,48 @@ synthesize_tinfo_var (target_type, real_name)
my_friendly_abort (20000117);
}
- return create_real_tinfo_var (real_name, TINFO_PSEUDO_TYPE (var_type), var_init);
+
+ return create_real_tinfo_var (real_name, TINFO_PSEUDO_TYPE (var_type),
+ var_init, non_public);
}
-/* Create the real typeinfo variable. */
+/* Create the real typeinfo variable. NON_PUBLIC indicates that we cannot
+ make this variable public (comdat). */
static tree
-create_real_tinfo_var (name, type, init)
+create_real_tinfo_var (name, type, init, non_public)
tree name;
tree type;
tree init;
+ int non_public;
{
+ static int count = 0;
tree decl;
+ tree hidden_name;
+ char hidden[30];
+
+ sprintf (hidden, "%.*s_%d",
+ IDENTIFIER_LENGTH (tinfo_decl_id), IDENTIFIER_POINTER (tinfo_decl_id),
+ count++);
+ hidden_name = get_identifier (hidden);
- decl = build_lang_decl (VAR_DECL, name,
+ decl = build_lang_decl (VAR_DECL, hidden_name,
build_qualified_type (type, TYPE_QUAL_CONST));
DECL_ARTIFICIAL (decl) = 1;
TREE_READONLY (decl) = 1;
TREE_STATIC (decl) = 1;
- TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 0;
- comdat_linkage (decl);
+ if (!non_public)
+ {
+ TREE_PUBLIC (decl) = 1;
+ comdat_linkage (decl);
+ }
DECL_ASSEMBLER_NAME (decl) = name;
DECL_INITIAL (decl) = init;
cp_finish_decl (decl, init, NULL_TREE, 0);
-
+ pushdecl_top_level (decl);
+ TREE_USED (decl) = 1;
return decl;
}
@@ -1951,7 +2035,7 @@ tinfo_decl_p (t, data)
actual type this is describing. The DECL_ASSEMBLER_NAME of the generated
definition is set to that of the supplied decl, so that they can be tied
up. Mark the supplied decl as having been dealt with. Emitting one
- definitions might cause other declarations to be emitted.
+ definition might cause other definitions to be required.
We need to do things this way, because we're trying to do something like
diff --git a/gcc/cp/tinfo2.cc b/gcc/cp/tinfo2.cc
index 3d3c66a61e9..2be647a54df 100644
--- a/gcc/cp/tinfo2.cc
+++ b/gcc/cp/tinfo2.cc
@@ -438,10 +438,5 @@ BUILTIN (v); BUILTIN (x); BUILTIN (l); BUILTIN (i); BUILTIN (s); BUILTIN (b);
BUILTIN (c); BUILTIN (w); BUILTIN (r); BUILTIN (d); BUILTIN (f);
BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc);
BUILTIN (Sc);
-#else
-// new abi
-
-// we need to define the fundamental type type_info's, but the name mangling is
-// not yet defined.
#endif
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 6b7cb69c1a2..aa4cd32180e 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2574,6 +2574,10 @@ build_x_function_call (function, params, decl)
TYPE_BINFO (type), LOOKUP_NORMAL);
}
+ if (TREE_CODE (function) == OFFSET_REF
+ && TREE_CODE (type) != METHOD_TYPE)
+ function = resolve_offset_ref (function);
+
if ((TREE_CODE (function) == FUNCTION_DECL
&& DECL_STATIC_FUNCTION_P (function))
|| (TREE_CODE (function) == TEMPLATE_DECL
@@ -2669,8 +2673,6 @@ build_x_function_call (function, params, decl)
return build_method_call (decl, function, params,
NULL_TREE, LOOKUP_NORMAL);
}
- else if (TREE_CODE (function) == OFFSET_REF)
- my_friendly_abort (20000406);
else if (TREE_CODE (function) == COMPONENT_REF
&& type == unknown_type_node)
{
diff --git a/gcc/cpperror.c b/gcc/cpperror.c
index 0e8afc4ffa9..e798b780715 100644
--- a/gcc/cpperror.c
+++ b/gcc/cpperror.c
@@ -25,6 +25,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config.h"
#include "system.h"
+#include "hashtab.h"
#include "cpplib.h"
#include "cpphash.h"
#include "intl.h"
diff --git a/gcc/cppexp.c b/gcc/cppexp.c
index 46757c581e9..1489dc96123 100644
--- a/gcc/cppexp.c
+++ b/gcc/cppexp.c
@@ -1,5 +1,6 @@
/* Parse C expressions for cpplib.
Copyright (C) 1987, 92, 94, 95, 97, 98, 1999, 2000 Free Software Foundation.
+ Contributed by Per Bothner, 1994.
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
@@ -14,19 +15,14 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
-
-Written by Per Bothner 1994. */
+Boston, MA 02111-1307, USA. */
/* Parse a C expression from text in a string */
#include "config.h"
#include "system.h"
#include "cpplib.h"
+#include "hashtab.h"
#include "cpphash.h"
#ifndef CHAR_TYPE_SIZE
@@ -352,7 +348,7 @@ parse_defined (pfile)
pfile->no_macro_expand++;
token = _cpp_get_directive_token (pfile);
- if (token == CPP_LPAREN)
+ if (token == CPP_OPEN_PAREN)
{
paren++;
CPP_SET_WRITTEN (pfile, old_written);
@@ -368,7 +364,7 @@ parse_defined (pfile)
if (paren)
{
- if (_cpp_get_directive_token (pfile) != CPP_RPAREN)
+ if (_cpp_get_directive_token (pfile) != CPP_CLOSE_PAREN)
goto oops;
}
CPP_SET_WRITTEN (pfile, old_written);
@@ -444,7 +440,7 @@ lex (pfile, skip_evaluation)
return parse_charconst (pfile, tok_start, tok_end);
case CPP_NAME:
- if (!strcmp (tok_start, "defined"))
+ if (!strncmp (tok_start, "defined", 7))
return parse_defined (pfile);
op.op = INT;
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 59ee7c76f03..ddf4439ce6d 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -18,17 +18,13 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding! */
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "hashtab.h"
#include "cpplib.h"
#include "cpphash.h"
-#include "hashtab.h"
#include "intl.h"
#include "mkdeps.h"
@@ -263,8 +259,8 @@ find_include_file (pfile, fname, search_start, ihash, before)
dummy.hash = _cpp_calc_hash (fname, strlen (fname));
path = (fname[0] == '/') ? ABSOLUTE_PATH : search_start;
slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
- (const void *)&dummy,
- dummy.hash, 1);
+ (const void *) &dummy,
+ dummy.hash, INSERT);
if (*slot && (ih = redundant_include_p (pfile, *slot, path)))
{
@@ -284,7 +280,7 @@ find_include_file (pfile, fname, search_start, ihash, before)
else
{
/* Search directory path, trying to open the file. */
- name = alloca (strlen (fname) + pfile->max_include_len
+ name = (char *) alloca (strlen (fname) + pfile->max_include_len
+ 2 + INCLUDE_LEN_FUDGE);
do
{
@@ -333,8 +329,8 @@ _cpp_fake_ihash (pfile, fname)
dummy.nshort = fname;
dummy.hash = _cpp_calc_hash (fname, strlen (fname));
slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
- (const void *)&dummy,
- dummy.hash, 1);
+ (const void *) &dummy,
+ dummy.hash, INSERT);
if (*slot)
return (*slot)->name;
ih = make_IHASH (fname, 0, ABSOLUTE_PATH, dummy.hash, slot);
@@ -670,10 +666,10 @@ cpp_read_file (pfile, fname)
dummy.hash = _cpp_calc_hash (fname, strlen (fname));
slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
(const void *) &dummy,
- dummy.hash, 1);
+ dummy.hash, INSERT);
if (*slot && (ih = redundant_include_p (pfile, *slot, ABSOLUTE_PATH)))
{
- if (ih == (IHASH *)-1)
+ if (ih == (IHASH *) -1)
return 1; /* Already included. */
}
else
@@ -1101,7 +1097,7 @@ hack_vms_include_specification (fullname)
/* The VMS part ends in a `]', and the preceding character is not a `.'.
-> PATH]:/name (basename = '/name', unixname = 'name')
We strip the `]', and then splice the two parts of the name in the
- usual way. Given the default locations for include files in cccp.c,
+ usual way. Given the default locations for include files,
we will only use this code if the user specifies alternate locations
with the /include (-I) switch on the command line. */
diff --git a/gcc/cpphash.c b/gcc/cpphash.c
index bead2140c06..439cc805f45 100644
--- a/gcc/cpphash.c
+++ b/gcc/cpphash.c
@@ -26,8 +26,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config.h"
#include "system.h"
#include "cpplib.h"
-#include "cpphash.h"
#include "hashtab.h"
+#include "cpphash.h"
+
#undef abort
static unsigned int hash_HASHNODE PARAMS ((const void *));
@@ -200,12 +201,13 @@ _cpp_lookup (pfile, name, len)
}
/* Find the hashtable slot for name "name". Used to insert or delete. */
+
HASHNODE **
_cpp_lookup_slot (pfile, name, len, insert, hash)
cpp_reader *pfile;
const U_CHAR *name;
int len;
- int insert;
+ enum insert_option insert;
unsigned long *hash;
{
const U_CHAR *bp;
@@ -214,7 +216,9 @@ _cpp_lookup_slot (pfile, name, len, insert, hash)
if (len < 0)
{
- for (bp = name; is_idchar (*bp); bp++);
+ for (bp = name; is_idchar (*bp); bp++)
+ ;
+
len = bp - name;
}
@@ -223,7 +227,7 @@ _cpp_lookup_slot (pfile, name, len, insert, hash)
dummy.hash = _cpp_calc_hash (name, len);
slot = (HASHNODE **) htab_find_slot_with_hash (pfile->hashtab,
- (void *)&dummy,
+ (void *) &dummy,
dummy.hash, insert);
if (insert)
*hash = dummy.hash;
@@ -331,7 +335,7 @@ collect_expansion (pfile, arglist)
CPP_SET_WRITTEN (pfile, here);
break;
- case CPP_STRINGIZE:
+ case CPP_HASH:
/* # is not special in object-like macros. It is special in
function-like macros with no args. (6.10.3.2 para 1.) */
if (arglist == NULL)
@@ -344,7 +348,7 @@ collect_expansion (pfile, arglist)
CPP_SET_WRITTEN (pfile, here); /* delete from replacement text */
break;
- case CPP_TOKPASTE:
+ case CPP_PASTE:
/* If the last token was an argument, discard this token and
any hspace between it and the argument's position. Then
mark the arg raw_after. */
@@ -401,7 +405,7 @@ collect_expansion (pfile, arglist)
case CPP_NAME:
for (i = 0; i < argc; i++)
if (!strncmp (tok, argv[i].name, argv[i].len)
- && ! is_idchar (tok[argv[i].len]))
+ && tok + argv[i].len == CPP_PWRITTEN (pfile))
goto addref;
/* fall through */
@@ -517,7 +521,6 @@ collect_expansion (pfile, arglist)
while (here > last && is_hspace (pfile->token_buffer [here-1]))
here--;
CPP_SET_WRITTEN (pfile, here);
- CPP_NUL_TERMINATE (pfile);
len = CPP_WRITTEN (pfile) - start + 1;
/* space for no-concat markers at either end */
exp = (U_CHAR *) xmalloc (len + 4);
@@ -574,10 +577,10 @@ collect_formal_parameters (pfile)
old_written = CPP_WRITTEN (pfile);
token = _cpp_get_directive_token (pfile);
- if (token != CPP_LPAREN)
+ if (token != CPP_OPEN_PAREN)
{
cpp_ice (pfile, "first token = %d not %d in collect_formal_parameters",
- token, CPP_LPAREN);
+ token, CPP_OPEN_PAREN);
goto invalid;
}
@@ -623,10 +626,10 @@ collect_formal_parameters (pfile)
argv[argc].len = 0;
break;
- case CPP_RPAREN:
+ case CPP_CLOSE_PAREN:
goto done;
- case CPP_3DOTS:
+ case CPP_ELLIPSIS:
goto rest_arg;
case CPP_VSPACE:
@@ -665,7 +668,7 @@ collect_formal_parameters (pfile)
argv[argc].rest_arg = 1;
token = _cpp_get_directive_token (pfile);
- if (token != CPP_RPAREN)
+ if (token != CPP_CLOSE_PAREN)
{
cpp_error (pfile, "another parameter follows `...'");
goto invalid;
@@ -773,10 +776,10 @@ macarg (pfile, rest_args)
if (!CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
return token;
break;
- case CPP_LPAREN:
+ case CPP_OPEN_PAREN:
paren++;
break;
- case CPP_RPAREN:
+ case CPP_CLOSE_PAREN:
if (--paren < 0)
goto found;
break;
@@ -834,7 +837,6 @@ _cpp_quote_string (pfile, src)
case '\0':
CPP_PUTC_Q (pfile, '\"');
- CPP_NUL_TERMINATE_Q (pfile);
return;
}
}
@@ -851,7 +853,6 @@ special_symbol (hp, pfile)
cpp_reader *pfile;
{
const char *buf;
- int len;
cpp_buffer *ip;
switch (hp->type)
@@ -859,6 +860,11 @@ special_symbol (hp, pfile)
case T_FILE:
case T_BASE_FILE:
ip = cpp_file_buffer (pfile);
+ if (ip == NULL)
+ {
+ CPP_PUTS (pfile, "\"\"", 2);
+ return;
+ }
if (hp->type == T_BASE_FILE)
while (CPP_PREV_BUFFER (ip) != NULL)
ip = CPP_PREV_BUFFER (ip);
@@ -870,10 +876,13 @@ special_symbol (hp, pfile)
case T_INCLUDE_LEVEL:
{
- int true_indepth = 1;
+ int true_indepth = 0;
ip = cpp_file_buffer (pfile);
- while ((ip = CPP_PREV_BUFFER (ip)) != NULL)
- true_indepth++;
+ while (ip)
+ {
+ true_indepth++;
+ ip = CPP_PREV_BUFFER (ip);
+ }
CPP_RESERVE (pfile, 10);
sprintf (CPP_PWRITTEN (pfile), "%d", true_indepth);
@@ -884,11 +893,10 @@ special_symbol (hp, pfile)
case T_STDC:
#ifdef STDC_0_IN_SYSTEM_HEADERS
ip = cpp_file_buffer (pfile);
- if (ip->system_header_p && !cpp_defined (pfile, DSC("__STRICT_ANSI__")))
+ if (ip && ip->system_header_p
+ && !cpp_defined (pfile, DSC("__STRICT_ANSI__")))
{
- CPP_RESERVE (pfile, 2);
- CPP_PUTC_Q (pfile, '0');
- CPP_NUL_TERMINATE_Q (pfile);
+ CPP_PUTC (pfile, '0');
return;
}
#endif
@@ -900,16 +908,18 @@ special_symbol (hp, pfile)
if (!buf)
return;
if (*buf == '\0')
- buf = "\r ";
+ buf = "\r \r ";
- len = strlen (buf);
- CPP_RESERVE (pfile, len + 1);
- CPP_PUTS_Q (pfile, buf, len);
- CPP_NUL_TERMINATE_Q (pfile);
+ CPP_PUTS (pfile, buf, strlen (buf));
return;
case T_SPECLINE:
ip = cpp_file_buffer (pfile);
+ if (ip == NULL)
+ {
+ CPP_PUTC (pfile, '0');
+ return;
+ }
CPP_RESERVE (pfile, 10);
sprintf (CPP_PWRITTEN (pfile), "%u", CPP_BUF_LINE (ip));
CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile)));
@@ -946,9 +956,7 @@ special_symbol (hp, pfile)
case T_POISON:
cpp_error (pfile, "attempt to use poisoned `%s'.", hp->name);
- CPP_RESERVE (pfile, 1);
- CPP_PUTC_Q (pfile, '0');
- CPP_NUL_TERMINATE_Q (pfile);
+ CPP_PUTC (pfile, '0');
break;
default:
@@ -983,8 +991,13 @@ _cpp_macroexpand (pfile, hp)
register int i;
ip = cpp_file_buffer (pfile);
- start_line = CPP_BUF_LINE (ip);
- start_column = CPP_BUF_COL (ip);
+ if (ip)
+ {
+ start_line = CPP_BUF_LINE (ip);
+ start_column = CPP_BUF_COL (ip);
+ }
+ else
+ start_line = start_column = 0;
/* Check for and handle special symbols. */
if (hp->type != T_MACRO)
@@ -1029,7 +1042,7 @@ _cpp_macroexpand (pfile, hp)
pfile->no_directives++;
token = cpp_get_non_space_token (pfile);
- if (token != CPP_LPAREN)
+ if (token != CPP_OPEN_PAREN)
cpp_ice (pfile, "macroexpand: unexpected token %d (wanted LPAREN)",
token);
CPP_ADJUST_WRITTEN (pfile, -1);
@@ -1059,17 +1072,17 @@ _cpp_macroexpand (pfile, hp)
CPP_OPTION (pfile, discard_comments)--;
pfile->no_macro_expand--;
pfile->no_directives--;
- if (token != CPP_RPAREN)
+ if (token != CPP_CLOSE_PAREN)
return;
- /* If we got one arg but it was just whitespace, call that 0 args. */
- if (i == 1)
+ /* foo ( ) is equivalent to foo () unless foo takes exactly one
+ argument, in which case the former is allowed and the latter
+ is not. XXX C99 is silent on this rule, but it seems
+ inconsistent to me. */
+ if (i == 1 && nargs != 1)
{
register U_CHAR *bp = ARG_BASE + args[0].raw;
register U_CHAR *lim = bp + args[0].raw_length;
- /* cpp.texi says for foo ( ) we provide one argument.
- However, if foo wants just 0 arguments, treat this as 0. */
- if (nargs == 0)
while (bp != lim && is_space(*bp))
bp++;
if (bp == lim)
@@ -1397,6 +1410,10 @@ unsafe_chars (pfile, c1, c2)
cpp_reader *pfile;
int c1, c2;
{
+ /* If c2 is EOF, that's always safe. */
+ if (c2 == EOF)
+ return 0;
+
switch (c1)
{
case EOF:
@@ -1478,14 +1495,13 @@ push_macro_expansion (pfile, xbuf, len, hp)
/* Likewise, avoid the extra space at the end of the macro expansion
if this is safe. We can do a better job here since we can know
what the next char will be. */
- if (len >= 3
- && xbuf[len-2] == '\r'
- && xbuf[len-1] == ' ')
- {
- int c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
- if (c == EOF || !unsafe_chars (pfile, xbuf[len-3], c))
- len -= 2;
- }
+ if (len >= 3 && xbuf[len-2] == '\r' && xbuf[len-1] == ' '
+ && !unsafe_chars (pfile, xbuf[len-3], CPP_BUF_PEEK (CPP_BUFFER (pfile))))
+ len -= 2;
+
+ /* If the total expansion is "\r \r", we must not trim both escapes. */
+ if (len == 2 && advance_cur)
+ advance_cur = 0;
mbuf = cpp_push_buffer (pfile, xbuf, len);
if (mbuf == NULL)
@@ -1688,7 +1704,6 @@ _cpp_dump_definition (pfile, sym, len, defn)
}
if (CPP_BUFFER (pfile) == 0 || ! pfile->done_initializing)
CPP_PUTC (pfile, '\n');
- CPP_NUL_TERMINATE (pfile);
}
/* Dump out the hash table. */
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index 99e45fb0c71..b0ac3c654b7 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -213,9 +213,6 @@ extern unsigned char _cpp_IStable[256];
#define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH))
/* Append character CH to PFILE's output buffer. Make space if need be. */
#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH))
-/* Make sure PFILE->limit is followed by '\0'. */
-#define CPP_NUL_TERMINATE_Q(PFILE) (*(PFILE)->limit = 0)
-#define CPP_NUL_TERMINATE(PFILE) (CPP_RESERVE(PFILE, 1), *(PFILE)->limit = 0)
/* Advance the current line by one. */
#define CPP_BUMP_BUFFER_LINE(PBUF) ((PBUF)->lineno++,\
@@ -271,7 +268,8 @@ extern unsigned int _cpp_calc_hash PARAMS ((const U_CHAR *, size_t));
extern HASHNODE *_cpp_lookup PARAMS ((cpp_reader *,
const U_CHAR *, int));
extern HASHNODE **_cpp_lookup_slot PARAMS ((cpp_reader *,
- const U_CHAR *, int, int,
+ const U_CHAR *, int,
+ enum insert_option,
unsigned long *));
extern void _cpp_free_definition PARAMS ((DEFINITION *));
extern DEFINITION *_cpp_create_definition PARAMS ((cpp_reader *, int));
@@ -311,6 +309,7 @@ extern enum cpp_ttype _cpp_get_directive_token
PARAMS ((cpp_reader *));
extern enum cpp_ttype _cpp_get_define_token
PARAMS ((cpp_reader *));
+extern void _cpp_scan_line PARAMS ((cpp_reader *, cpp_toklist *));
/* In cpplib.c */
extern int _cpp_handle_directive PARAMS ((cpp_reader *));
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 5174da8d5bf..d1e7c117b26 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -21,14 +21,13 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-
+#include "hashtab.h"
#include "cpplib.h"
#include "cpphash.h"
#include "output.h"
#include "prefix.h"
#include "intl.h"
#include "version.h"
-#include "hashtab.h"
#include "mkdeps.h"
/* Predefined symbols, built-in macros, and the default include path. */
@@ -683,7 +682,7 @@ initialize_builtins (pfile)
hp = _cpp_make_hashnode (b->name, len, b->type,
_cpp_calc_hash (b->name, len));
hp->value.cpval = val;
- *(htab_find_slot (pfile->hashtab, (void *)hp, 1)) = hp;
+ *(htab_find_slot (pfile->hashtab, (void *) hp, INSERT)) = hp;
if ((b->flags & DUMP) && CPP_OPTION (pfile, debug_output))
dump_special_to_buffer (pfile, b->name);
@@ -795,7 +794,7 @@ initialize_standard_includes (pfile)
These have /usr/local/lib/gcc... replaced by specd_prefix. */
if (specd_prefix != 0)
{
- char *default_prefix = alloca (sizeof GCC_INCLUDE_DIR - 7);
+ char *default_prefix = (char *) alloca (sizeof GCC_INCLUDE_DIR - 7);
/* Remove the `include' from /usr/local/lib/gcc.../include.
GCC_INCLUDE_DIR will always end in /include. */
int default_len = sizeof GCC_INCLUDE_DIR - 8;
@@ -1280,7 +1279,7 @@ handle_option (pfile, argc, argv)
arg = argv[++i];
if (!arg)
{
- cpp_fatal (pfile, _(cl_options[opt_index].msg), argv[i - 1]);
+ cpp_fatal (pfile, cl_options[opt_index].msg, argv[i - 1]);
return argc;
}
}
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 08133595a71..deae87e9447 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -22,6 +22,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "intl.h"
+#include "hashtab.h"
#include "cpplib.h"
#include "cpphash.h"
@@ -49,7 +50,13 @@ static void null_warning PARAMS ((cpp_reader *, unsigned int));
static void safe_fwrite PARAMS ((cpp_reader *, const U_CHAR *,
size_t, FILE *));
-static void output_line_command PARAMS ((cpp_reader *, cpp_printer *));
+static void output_line_command PARAMS ((cpp_reader *, cpp_printer *,
+ unsigned int));
+static void bump_column PARAMS ((cpp_printer *, unsigned int,
+ unsigned int));
+static void expand_name_space PARAMS ((cpp_toklist *));
+static void expand_token_space PARAMS ((cpp_toklist *));
+static void init_token_list PARAMS ((cpp_reader *, cpp_toklist *, int));
/* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */
@@ -148,25 +155,18 @@ safe_fwrite (pfile, buf, len, fp)
or the current file name has changed. */
static void
-output_line_command (pfile, print)
+output_line_command (pfile, print, line)
cpp_reader *pfile;
cpp_printer *print;
+ unsigned int line;
{
- unsigned int line;
- cpp_buffer *ip;
+ cpp_buffer *ip = cpp_file_buffer (pfile);
enum { same = 0, enter, leave, rname } change;
static const char * const codes[] = { "", " 1", " 2", "" };
if (CPP_OPTION (pfile, no_line_commands))
return;
- ip = cpp_file_buffer (pfile);
- if (ip == NULL)
- return;
- line = CPP_BUF_LINE (ip);
-
- // fprintf (print->outf, "[%u %u", print->lineno, line);
-
/* Determine whether the current filename has changed, and if so,
how. 'nominal_fname' values are unique, so they can be compared
by comparing pointers. */
@@ -199,7 +199,6 @@ output_line_command (pfile, print)
putc ('\n', print->outf);
print->lineno++;
}
- // putc(']', print->outf);
return;
}
@@ -226,14 +225,88 @@ cpp_output_tokens (pfile, print)
cpp_reader *pfile;
cpp_printer *print;
{
- if (CPP_PWRITTEN (pfile)[-1] == '\n' && print->lineno)
- print->lineno++;
- safe_fwrite (pfile, pfile->token_buffer,
- CPP_WRITTEN (pfile) - print->written, print->outf);
- output_line_command (pfile, print);
+ cpp_buffer *ip;
+
+ if (CPP_WRITTEN (pfile) - print->written)
+ {
+ if (CPP_PWRITTEN (pfile)[-1] == '\n' && print->lineno)
+ print->lineno++;
+ safe_fwrite (pfile, pfile->token_buffer,
+ CPP_WRITTEN (pfile) - print->written, print->outf);
+ }
+
+ ip = cpp_file_buffer (pfile);
+ if (ip)
+ output_line_command (pfile, print, CPP_BUF_LINE (ip));
+
CPP_SET_WRITTEN (pfile, print->written);
}
+/* Helper for cpp_output_list - increases the column number to match
+ what we expect it to be. */
+
+static void
+bump_column (print, from, to)
+ cpp_printer *print;
+ unsigned int from, to;
+{
+ unsigned int tabs, spcs;
+ unsigned int delta = to - from;
+
+ /* Only if FROM is 0, advance by tabs. */
+ if (from == 0)
+ tabs = delta / 8, spcs = delta % 8;
+ else
+ tabs = 0, spcs = delta;
+
+ while (tabs--) putc ('\t', print->outf);
+ while (spcs--) putc (' ', print->outf);
+}
+
+/* Write out the list L onto pfile->token_buffer. This function is
+ incomplete:
+
+ 1) pfile->token_buffer is not going to continue to exist.
+ 2) At the moment, tokens don't carry the information described
+ in cpplib.h; they are all strings.
+ 3) The list has to be a complete line, and has to be written starting
+ at the beginning of a line. */
+
+void
+cpp_output_list (pfile, print, list)
+ cpp_reader *pfile;
+ cpp_printer *print;
+ const cpp_toklist *list;
+{
+ unsigned int i;
+ unsigned int curcol = 1;
+
+ /* XXX Probably does not do what is intended. */
+ if (print->lineno != list->line)
+ output_line_command (pfile, print, list->line);
+
+ for (i = 0; i < list->tokens_used; i++)
+ {
+ if (list->tokens[i].type == CPP_VSPACE)
+ {
+ output_line_command (pfile, print, list->tokens[i].aux);
+ continue;
+ }
+
+ if (curcol < list->tokens[i].col)
+ {
+ /* Insert space to bring the column to what it should be. */
+ bump_column (print, curcol - 1, list->tokens[i].col);
+ curcol = list->tokens[i].col;
+ }
+ /* XXX We may have to insert space to prevent an accidental
+ token paste. */
+ safe_fwrite (pfile, list->namebuf + list->tokens[i].val.name.offset,
+ list->tokens[i].val.name.len, print->outf);
+ curcol += list->tokens[i].val.name.len;
+ }
+}
+
/* Scan a string (which may have escape marks), perform macro expansion,
and write the result to the token_buffer. */
@@ -245,6 +318,7 @@ _cpp_expand_to_buffer (pfile, buf, length)
{
cpp_buffer *ip;
enum cpp_ttype token;
+ U_CHAR *buf1;
if (length < 0)
{
@@ -252,8 +326,14 @@ _cpp_expand_to_buffer (pfile, buf, length)
return;
}
+ /* Copy the buffer, because it might be in an unsafe place - for
+ example, a sequence on the token_buffer, where the pointers will
+ be invalidated if we enlarge the token_buffer. */
+ buf1 = alloca (length);
+ memcpy (buf1, buf, length);
+
/* Set up the input on the input stack. */
- ip = cpp_push_buffer (pfile, buf, length);
+ ip = cpp_push_buffer (pfile, buf1, length);
if (ip == NULL)
return;
ip->has_escapes = 1;
@@ -270,7 +350,6 @@ _cpp_expand_to_buffer (pfile, buf, length)
break;
}
}
- CPP_NUL_TERMINATE (pfile);
}
/* Scan until CPP_BUFFER (PFILE) is exhausted, discarding output.
@@ -346,6 +425,107 @@ cpp_file_buffer (pfile)
return NULL;
}
+/* Token-buffer helper functions. */
+
+/* Expand a token list's string space. */
+static void
+expand_name_space (list)
+ cpp_toklist *list;
+{
+ list->name_cap *= 2;
+ list->namebuf = (unsigned char *) xrealloc (list->namebuf,
+ list->name_cap);
+}
+
+/* Expand the number of tokens in a list. */
+static void
+expand_token_space (list)
+ cpp_toklist *list;
+{
+ list->tokens_cap *= 2;
+ list->tokens = (cpp_token *)
+ xrealloc (list->tokens, list->tokens_cap * sizeof (cpp_token));
+}
+
+/* Initialise a token list. */
+static void
+init_token_list (pfile, list, recycle)
+ cpp_reader *pfile;
+ cpp_toklist *list;
+ int recycle;
+{
+ /* Recycling a used list saves 2 free-malloc pairs. */
+ if (recycle)
+ {
+ list->tokens_used = 0;
+ list->name_used = 0;
+ }
+ else
+ {
+ /* Initialise token space. */
+ list->tokens_cap = 256; /* 4K on Intel. */
+ list->tokens_used = 0;
+ list->tokens = (cpp_token *)
+ xmalloc (list->tokens_cap * sizeof (cpp_token));
+
+ /* Initialise name space. */
+ list->name_cap = 1024;
+ list->name_used = 0;
+ list->namebuf = (unsigned char *) xmalloc (list->name_cap);
+ }
+
+ list->line = pfile->buffer->lineno;
+ list->dir_handler = 0;
+ list->dir_flags = 0;
+}
+
+/* Scan an entire line and create a token list for it. Does not
+ macro-expand or execute directives. */
+
+void
+_cpp_scan_line (pfile, list)
+ cpp_reader *pfile;
+ cpp_toklist *list;
+{
+ int i, col;
+ long written, len;
+ enum cpp_ttype type;
+
+ init_token_list (pfile, list, 1);
+
+ written = CPP_WRITTEN (pfile);
+ i = 0;
+ for (;;)
+ {
+ col = CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base;
+ type = _cpp_lex_token (pfile);
+ len = CPP_WRITTEN (pfile) - written;
+ CPP_SET_WRITTEN (pfile, written);
+ if (type == CPP_HSPACE)
+ continue;
+
+ if (list->tokens_used >= list->tokens_cap)
+ expand_token_space (list);
+ if (list->name_used + len >= list->name_cap)
+ expand_name_space (list);
+
+ list->tokens_used++;
+ list->tokens[i].type = type;
+ list->tokens[i].col = col;
+
+ if (type == CPP_VSPACE)
+ break;
+
+ list->tokens[i].val.name.len = len;
+ list->tokens[i].val.name.offset = list->name_used;
+ memcpy (list->namebuf + list->name_used, CPP_PWRITTEN (pfile), len);
+ list->name_used += len;
+ i++;
+ }
+ list->tokens[i].aux = CPP_BUFFER (pfile)->lineno + 1;
+}
+
+
/* Skip a C-style block comment. We know it's a comment, and point is
at the second character of the starter. */
static void
@@ -623,7 +803,6 @@ _cpp_parse_name (pfile, c)
if (c == EOF)
break;
}
- CPP_NUL_TERMINATE_Q (pfile);
return;
}
@@ -898,9 +1077,9 @@ _cpp_lex_token (pfile)
CPP_PUTC_Q (pfile, GETC ());
}
else
- return CPP_STRINGIZE;
+ return CPP_HASH;
- return CPP_TOKPASTE;
+ return CPP_PASTE;
}
if (!pfile->only_seen_white)
@@ -953,7 +1132,7 @@ _cpp_lex_token (pfile)
CPP_RESERVE (pfile, 2);
CPP_PUTC_Q (pfile, c);
CPP_PUTC_Q (pfile, c2);
- return CPP_RBRACE;
+ return CPP_OPEN_BRACE;
}
/* else fall through */
@@ -1036,7 +1215,7 @@ _cpp_lex_token (pfile)
CPP_RESERVE (pfile, 2);
CPP_PUTC_Q (pfile, c);
CPP_PUTC_Q (pfile, c2);
- return CPP_LBRACE;
+ return CPP_CLOSE_BRACE;
}
else if (c2 == ':')
goto op2;
@@ -1076,7 +1255,7 @@ _cpp_lex_token (pfile)
CPP_PUTC_Q (pfile, '.');
CPP_PUTC_Q (pfile, '.');
FORWARD (2);
- return CPP_3DOTS;
+ return CPP_ELLIPSIS;
}
goto randomchar;
@@ -1117,7 +1296,6 @@ _cpp_lex_token (pfile)
FORWARD(1);
c2= c;
}
- CPP_NUL_TERMINATE_Q (pfile);
return CPP_NUMBER;
case 'b': case 'c': case 'd': case 'h': case 'o':
case 'B': case 'C': case 'D': case 'H': case 'O':
@@ -1140,14 +1318,12 @@ _cpp_lex_token (pfile)
{
CPP_RESERVE (pfile, 2);
CPP_PUTC_Q (pfile, c);
- CPP_NUL_TERMINATE_Q (pfile);
return CPP_STRING;
}
else
{
FORWARD(-1);
chill_number_eof:
- CPP_NUL_TERMINATE (pfile);
return CPP_NUMBER;
}
}
@@ -1216,7 +1392,8 @@ _cpp_lex_token (pfile)
else
{
/* Backslash newline is ignored. */
- CPP_BUMP_LINE (pfile);
+ if (!ACTIVE_MARK_P (pfile))
+ CPP_BUMP_LINE (pfile);
goto get_next;
}
@@ -1224,12 +1401,12 @@ _cpp_lex_token (pfile)
CPP_PUTC (pfile, c);
return CPP_VSPACE;
- case '(': token = CPP_LPAREN; goto char1;
- case ')': token = CPP_RPAREN; goto char1;
- case '{': token = CPP_LBRACE; goto char1;
- case '}': token = CPP_RBRACE; goto char1;
- case ',': token = CPP_COMMA; goto char1;
- case ';': token = CPP_SEMICOLON; goto char1;
+ case '(': token = CPP_OPEN_PAREN; goto char1;
+ case ')': token = CPP_CLOSE_PAREN; goto char1;
+ case '{': token = CPP_OPEN_BRACE; goto char1;
+ case '}': token = CPP_CLOSE_BRACE; goto char1;
+ case ',': token = CPP_COMMA; goto char1;
+ case ';': token = CPP_SEMICOLON; goto char1;
randomchar:
default:
@@ -1631,12 +1808,6 @@ _cpp_read_and_prescan (pfile, fp, desc, len)
{
U_CHAR *near_buff_end;
- /* Copy previous char plus unprocessed (at most 2) chars
- to beginning of buffer, refill it with another
- read(), and continue processing */
- memcpy(ip - count - 1, ip - 1, 3);
- ip -= count;
-
count = read (desc, ibase, pfile->input_buffer_len);
if (count < 0)
goto error;
@@ -1650,7 +1821,7 @@ _cpp_read_and_prescan (pfile, fp, desc, len)
{
size_t delta_op;
size_t delta_line_base;
- len *= 2;
+ len = offset * 2;
if (offset > len)
/* len overflowed.
This could happen if the file is larger than half the
@@ -1785,6 +1956,11 @@ _cpp_read_and_prescan (pfile, fp, desc, len)
break;
}
}
+ /* Copy previous char plus unprocessed (at most 2) chars
+ to beginning of buffer, refill it with another
+ read(), and continue processing */
+ memmove (ip - count - 1, ip - 1, 4 - (ip - near_buff_end));
+ ip -= count;
}
if (offset == 0)
@@ -1795,7 +1971,7 @@ _cpp_read_and_prescan (pfile, fp, desc, len)
unsigned long col;
line_base = find_position (line_base, op, &line);
col = op - line_base + 1;
- cpp_warning_with_line (pfile, line, col, "no newline at end of file\n");
+ cpp_warning_with_line (pfile, line, col, "no newline at end of file");
if (offset + 1 > len)
{
len += 1;
@@ -1811,7 +1987,8 @@ _cpp_read_and_prescan (pfile, fp, desc, len)
return op - buf;
too_big:
- cpp_error (pfile, "file is too large (>%lu bytes)\n", (unsigned long)offset);
+ cpp_notice (pfile, "%s is too large (>%lu bytes)", fp->ihash->name,
+ (unsigned long)offset);
free (buf);
return -1;
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 3549bed8f74..fb6b7709949 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -22,6 +22,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "hashtab.h"
#include "cpplib.h"
#include "cpphash.h"
#include "hashtab.h"
@@ -32,11 +33,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
struct directive
{
- int (*func) /* Function to handle directive */
- PARAMS ((cpp_reader *));
- const char *name; /* Name of directive */
- unsigned short length; /* Length of name */
- unsigned short origin; /* Origin of this directive */
+ directive_handler func; /* Function to handle directive. */
+ const char *name; /* Name of directive. */
+ unsigned short length; /* Length of name. */
+ unsigned short flags; /* Flags describing this directive. */
};
/* Stack of conditionals currently in progress
@@ -68,14 +68,20 @@ static int consider_directive_while_skipping
PARAMS ((cpp_reader *, IF_STACK *));
static int get_macro_name PARAMS ((cpp_reader *));
-/* Values for the "origin" field of the table below. KANDR and COND
+/* Values for the flags field of the table below. KANDR and COND
directives come from traditional (K&R) C. The difference is, if we
care about it while skipping a failed conditional block, its origin
is COND. STDC89 directives come from the 1989 C standard.
EXTENSION directives are extensions, with origins noted below. */
-enum { KANDR = 0, COND, STDC89, EXTENSION };
-#define TRAD_DIRECT_P(x) ((x) == KANDR || (x) == COND)
+#define KANDR 0
+#define COND 1
+#define STDC89 2
+#define EXTENSION 3
+
+#define ORIGIN_MASK 3
+#define ORIGIN(f) ((f) & ORIGIN_MASK)
+#define TRAD_DIRECT_P(f) (ORIGIN (f) == KANDR || ORIGIN (f) == COND)
/* This is the table of directive handlers. It is ordered by
frequency of occurrence; the numbers at the end are directive
@@ -94,25 +100,25 @@ enum { KANDR = 0, COND, STDC89, EXTENSION };
# define SCCS_ENTRY /* nothing */
#endif
-#define DIRECTIVE_TABLE \
-D(define, T_DEFINE = 0, KANDR) /* 270554 */ \
-D(include, T_INCLUDE, KANDR) /* 52262 */ \
-D(endif, T_ENDIF, COND) /* 45855 */ \
-D(ifdef, T_IFDEF, COND) /* 22000 */ \
-D(if, T_IF, COND) /* 18162 */ \
-D(else, T_ELSE, COND) /* 9863 */ \
-D(ifndef, T_IFNDEF, COND) /* 9675 */ \
-D(undef, T_UNDEF, KANDR) /* 4837 */ \
-D(line, T_LINE, KANDR) /* 2465 */ \
-D(elif, T_ELIF, COND) /* 610 */ \
-D(error, T_ERROR, STDC89) /* 475 */ \
-D(pragma, T_PRAGMA, STDC89) /* 195 */ \
-D(warning, T_WARNING, EXTENSION) /* 22 - GNU */ \
-D(include_next, T_INCLUDE_NEXT, EXTENSION) /* 19 - GNU */ \
-D(ident, T_IDENT, EXTENSION) /* 11 - SVR4 */ \
-D(import, T_IMPORT, EXTENSION) /* 0 - ObjC */ \
-D(assert, T_ASSERT, EXTENSION) /* 0 - SVR4 */ \
-D(unassert, T_UNASSERT, EXTENSION) /* 0 - SVR4 */ \
+#define DIRECTIVE_TABLE \
+D(define, T_DEFINE = 0, KANDR) /* 270554 */ \
+D(include, T_INCLUDE, KANDR | SYNTAX_INCLUDE) /* 52262 */ \
+D(endif, T_ENDIF, COND) /* 45855 */ \
+D(ifdef, T_IFDEF, COND) /* 22000 */ \
+D(if, T_IF, COND) /* 18162 */ \
+D(else, T_ELSE, COND) /* 9863 */ \
+D(ifndef, T_IFNDEF, COND) /* 9675 */ \
+D(undef, T_UNDEF, KANDR) /* 4837 */ \
+D(line, T_LINE, KANDR) /* 2465 */ \
+D(elif, T_ELIF, COND) /* 610 */ \
+D(error, T_ERROR, STDC89) /* 475 */ \
+D(pragma, T_PRAGMA, STDC89) /* 195 */ \
+D(warning, T_WARNING, EXTENSION) /* 22 GNU */ \
+D(include_next, T_INCLUDE_NEXT, EXTENSION | SYNTAX_INCLUDE) /* 19 GNU */ \
+D(ident, T_IDENT, EXTENSION) /* 11 SVR4 */ \
+D(import, T_IMPORT, EXTENSION | SYNTAX_INCLUDE) /* 0 ObjC */ \
+D(assert, T_ASSERT, EXTENSION | SYNTAX_ASSERT) /* 0 SVR4 */ \
+D(unassert, T_UNASSERT, EXTENSION | SYNTAX_ASSERT) /* 0 SVR4 */ \
SCCS_ENTRY
/* Use the table to generate a series of prototypes, an enum for the
@@ -123,11 +129,11 @@ SCCS_ENTRY
pointers to functions returning void. */
/* Don't invoke CONCAT2 with any whitespace or K&R cc will fail. */
-#define D(name, t, o) static int CONCAT2(do_,name) PARAMS ((cpp_reader *));
+#define D(name, t, f) static int CONCAT2(do_,name) PARAMS ((cpp_reader *));
DIRECTIVE_TABLE
#undef D
-#define D(n, tag, o) tag,
+#define D(n, tag, f) tag,
enum
{
DIRECTIVE_TABLE
@@ -136,8 +142,8 @@ enum
#undef D
/* Don't invoke CONCAT2 with any whitespace or K&R cc will fail. */
-#define D(name, t, origin) \
-{ CONCAT2(do_,name), STRINGX(name), sizeof STRINGX(name) - 1, origin },
+#define D(name, t, flags) \
+{ CONCAT2(do_,name), STRINGX(name), sizeof STRINGX(name) - 1, flags },
static const struct directive dtable[] =
{
DIRECTIVE_TABLE
@@ -249,17 +255,17 @@ _cpp_handle_directive (pfile)
}
/* Issue -pedantic warnings for extended directives. */
- if (CPP_PEDANTIC (pfile) && dtable[i].origin == EXTENSION)
+ if (CPP_PEDANTIC (pfile) && ORIGIN (dtable[i].flags) == EXTENSION)
cpp_pedwarn (pfile, "ISO C does not allow #%s", dtable[i].name);
/* -Wtraditional gives warnings about directives with inappropriate
indentation of #. */
if (CPP_WTRADITIONAL (pfile))
{
- if (!hash_at_bol && TRAD_DIRECT_P (dtable[i].origin))
+ if (!hash_at_bol && TRAD_DIRECT_P (dtable[i].flags))
cpp_warning (pfile, "traditional C ignores #%s with the # indented",
dtable[i].name);
- else if (hash_at_bol && ! TRAD_DIRECT_P (dtable[i].origin))
+ else if (hash_at_bol && ! TRAD_DIRECT_P (dtable[i].flags))
cpp_warning (pfile,
"suggest hiding #%s from traditional C with an indented #",
dtable[i].name);
@@ -371,7 +377,7 @@ do_define (pfile)
token = _cpp_get_directive_token (pfile);
if (token == CPP_VSPACE)
empty = 0; /* Empty definition of object like macro. */
- else if (token == CPP_LPAREN && ADJACENT_TO_MARK (pfile))
+ else if (token == CPP_OPEN_PAREN && ADJACENT_TO_MARK (pfile))
funlike = 1;
else if (ADJACENT_TO_MARK (pfile))
/* If this is an object-like macro, C99 requires white space after
@@ -387,7 +393,7 @@ do_define (pfile)
goto out;
}
- slot = _cpp_lookup_slot (pfile, sym, len, 1, &hash);
+ slot = _cpp_lookup_slot (pfile, sym, len, INSERT, &hash);
if (*slot)
{
int ok;
@@ -500,9 +506,6 @@ parse_include (pfile, name)
return 0;
}
- CPP_NUL_TERMINATE (pfile);
- CPP_ADJUST_WRITTEN (pfile, 1);
-
if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
{
cpp_error (pfile, "junk at end of `#%s'", name);
@@ -528,7 +531,8 @@ do_include (pfile)
if (len == 0)
return 0;
token = alloca (len + 1);
- strcpy (token, CPP_PWRITTEN (pfile));
+ memcpy (token, CPP_PWRITTEN (pfile), len);
+ token[len] = '\0';
if (CPP_OPTION (pfile, dump_includes))
pass_thru_directive (token, len, pfile, T_INCLUDE);
@@ -556,7 +560,8 @@ do_import (pfile)
if (len == 0)
return 0;
token = alloca (len + 1);
- strcpy (token, CPP_PWRITTEN (pfile));
+ memcpy (token, CPP_PWRITTEN (pfile), len);
+ token[len] = '\0';
if (CPP_OPTION (pfile, dump_includes))
pass_thru_directive (token, len, pfile, T_IMPORT);
@@ -577,7 +582,8 @@ do_include_next (pfile)
if (len == 0)
return 0;
token = alloca (len + 1);
- strcpy (token, CPP_PWRITTEN (pfile));
+ memcpy (token, CPP_PWRITTEN (pfile), len);
+ token[len] = '\0';
if (CPP_OPTION (pfile, dump_includes))
pass_thru_directive (token, len, pfile, T_INCLUDE_NEXT);
@@ -611,18 +617,20 @@ read_line_number (pfile, num)
long save_written = CPP_WRITTEN (pfile);
U_CHAR *p;
enum cpp_ttype token = _cpp_get_directive_token (pfile);
- CPP_SET_WRITTEN (pfile, save_written);
p = pfile->token_buffer + save_written;
- if (token == CPP_NUMBER && *p >= '1' && *p <= '4' && p[1] == '\0')
+ if (token == CPP_NUMBER && p + 1 == CPP_PWRITTEN (pfile)
+ && p[0] >= '1' && p[0] <= '4')
{
*num = p[0] - '0';
+ CPP_SET_WRITTEN (pfile, save_written);
return 1;
}
else
{
if (token != CPP_VSPACE && token != CPP_EOF)
cpp_error (pfile, "invalid format `#line' command");
+ CPP_SET_WRITTEN (pfile, save_written);
return 0;
}
}
@@ -649,6 +657,7 @@ do_line (pfile)
goto bad_line_directive;
}
+ CPP_PUTC (pfile, '\0'); /* not terminated for us */
new_lineno = strtoul (pfile->token_buffer + old_written, &x, 10);
if (x[0] != '\0')
{
@@ -679,11 +688,13 @@ do_line (pfile)
if (action_number == 1)
{
pfile->buffer_stack_depth++;
+ ip->system_header_p = 0;
read_line_number (pfile, &action_number);
}
else if (action_number == 2)
{
pfile->buffer_stack_depth--;
+ ip->system_header_p = 0;
read_line_number (pfile, &action_number);
}
if (action_number == 3)
@@ -762,7 +773,7 @@ do_undef (pfile)
name = pfile->token_buffer + here;
CPP_SET_WRITTEN (pfile, here);
- slot = _cpp_lookup_slot (pfile, name, len, 0, 0);
+ slot = _cpp_lookup_slot (pfile, name, len, NO_INSERT, 0);
if (slot)
{
HASHNODE *hp = *slot;
@@ -1019,14 +1030,14 @@ do_pragma_poison (pfile)
}
p = pfile->token_buffer + written;
- len = strlen (p);
- slot = _cpp_lookup_slot (pfile, p, len, 1, &hash);
+ len = CPP_PWRITTEN (pfile) - p;
+ slot = _cpp_lookup_slot (pfile, p, len, INSERT, &hash);
if (*slot)
{
HASHNODE *hp = *slot;
if (hp->type != T_POISON)
{
- cpp_warning (pfile, "poisoning existing macro `%s'", p);
+ cpp_warning (pfile, "poisoning existing macro `%s'", hp->name);
if (hp->type == T_MACRO)
_cpp_free_definition (hp->value.defn);
hp->value.defn = 0;
@@ -1061,71 +1072,72 @@ do_sccs (pfile)
`#if ! defined SYMBOL', then SYMBOL is a possible controlling macro
for inclusion of this file. (See redundant_include_p in cppfiles.c
for an explanation of controlling macros.) If so, return a
- malloc'd copy of SYMBOL. Otherwise, return NULL. */
+ malloced copy of SYMBOL. Otherwise, return NULL. */
static U_CHAR *
detect_if_not_defined (pfile)
cpp_reader *pfile;
{
U_CHAR *control_macro = 0;
+ enum cpp_ttype token;
+ unsigned int base_offset;
+ unsigned int token_offset;
+ unsigned int need_rparen = 0;
+ unsigned int token_len;
- if (pfile->only_seen_white == 2)
- {
- U_CHAR *ident;
- enum cpp_ttype token;
- int base_offset;
- int token_offset;
- int need_rparen = 0;
-
- /* Save state required for restore. */
- pfile->no_macro_expand++;
- CPP_SET_MARK (pfile);
- base_offset = CPP_WRITTEN (pfile);
-
- /* Look for `!', */
- if (_cpp_get_directive_token (pfile) != CPP_OTHER
- || CPP_WRITTEN (pfile) != (size_t) base_offset + 1
- || CPP_PWRITTEN (pfile)[-1] != '!')
- goto restore;
-
- /* ...then `defined', */
- token_offset = CPP_WRITTEN (pfile);
- token = _cpp_get_directive_token (pfile);
- if (token != CPP_NAME)
- goto restore;
- ident = pfile->token_buffer + token_offset;
- CPP_NUL_TERMINATE (pfile);
- if (strcmp (ident, "defined"))
- goto restore;
+ if (pfile->only_seen_white != 2)
+ return NULL;
+
+ /* Save state required for restore. */
+ pfile->no_macro_expand++;
+ CPP_SET_MARK (pfile);
+ base_offset = CPP_WRITTEN (pfile);
+
+ /* Look for `!', */
+ if (_cpp_get_directive_token (pfile) != CPP_OTHER
+ || CPP_WRITTEN (pfile) != (size_t) base_offset + 1
+ || CPP_PWRITTEN (pfile)[-1] != '!')
+ goto restore;
+
+ /* ...then `defined', */
+ token_offset = CPP_WRITTEN (pfile);
+ token = _cpp_get_directive_token (pfile);
+ if (token != CPP_NAME)
+ goto restore;
+ if (strncmp (pfile->token_buffer + token_offset, "defined", 7))
+ goto restore;
- /* ...then an optional '(' and the name, */
+ /* ...then an optional '(' and the name, */
+ token_offset = CPP_WRITTEN (pfile);
+ token = _cpp_get_directive_token (pfile);
+ if (token == CPP_OPEN_PAREN)
+ {
token_offset = CPP_WRITTEN (pfile);
+ need_rparen = 1;
token = _cpp_get_directive_token (pfile);
- if (token == CPP_LPAREN)
- {
- token_offset = CPP_WRITTEN (pfile);
- token = _cpp_get_directive_token (pfile);
- if (token != CPP_NAME)
- goto restore;
- need_rparen = 1;
- }
- else if (token != CPP_NAME)
- goto restore;
-
- ident = pfile->token_buffer + token_offset;
- CPP_NUL_TERMINATE (pfile);
-
- /* ...then the ')', if necessary, */
- if ((!need_rparen || _cpp_get_directive_token (pfile) == CPP_RPAREN)
- /* ...and make sure there's nothing else on the line. */
- && _cpp_get_directive_token (pfile) == CPP_VSPACE)
- control_macro = (U_CHAR *) xstrdup (ident);
-
- restore:
- CPP_SET_WRITTEN (pfile, base_offset);
- pfile->no_macro_expand--;
- CPP_GOTO_MARK (pfile);
}
+ if (token != CPP_NAME)
+ goto restore;
+
+ token_len = CPP_WRITTEN (pfile) - token_offset;
+
+ /* ...then the ')', if necessary, */
+ if (need_rparen && _cpp_get_directive_token (pfile) != CPP_CLOSE_PAREN)
+ goto restore;
+
+ /* ...and make sure there's nothing else on the line. */
+ if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
+ goto restore;
+
+ /* We have a legitimate controlling macro for this header. */
+ control_macro = (U_CHAR *) xmalloc (token_len + 1);
+ memcpy (control_macro, pfile->token_buffer + token_offset, token_len);
+ control_macro[token_len] = '\0';
+
+ restore:
+ CPP_SET_WRITTEN (pfile, base_offset);
+ pfile->no_macro_expand--;
+ CPP_GOTO_MARK (pfile);
return control_macro;
}
@@ -1213,8 +1225,7 @@ parse_ifdef (pfile, name)
else if (token == CPP_NAME)
{
defined = cpp_defined (pfile, ident, len);
- CPP_NUL_TERMINATE (pfile);
- CPP_ADJUST_WRITTEN (pfile, 1);
+ CPP_PUTC (pfile, '\0'); /* so it can be copied with xstrdup */
}
else
{
@@ -1331,7 +1342,7 @@ consider_directive_while_skipping (pfile, stack)
real_directive:
/* If it's not a directive of interest to us, return now. */
- if (dtable[i].origin != COND)
+ if (ORIGIN (dtable[i].flags) != COND)
return 0;
/* First, deal with -traditional and -Wtraditional.
@@ -1578,14 +1589,14 @@ do_assert (pfile)
sym = pfile->token_buffer + old_written;
blen = (U_CHAR *) strchr (sym, '(') - sym;
- tslot = _cpp_lookup_slot (pfile, sym, tlen, 1, &thash);
+ tslot = _cpp_lookup_slot (pfile, sym, tlen, INSERT, &thash);
if (*tslot)
{
cpp_warning (pfile, "%s re-asserted", sym);
goto error;
}
- bslot = _cpp_lookup_slot (pfile, sym, blen, 1, &bhash);
+ bslot = _cpp_lookup_slot (pfile, sym, blen, INSERT, &bhash);
if (! *bslot)
{
*bslot = base = _cpp_make_hashnode (sym, blen, T_ASSERT, bhash);
@@ -1700,7 +1711,7 @@ cpp_define (pfile, str)
if (p)
{
count = strlen (str) + 2;
- buf = alloca (count);
+ buf = (char *) alloca (count);
memcpy (buf, str, count - 2);
buf[p - str] = ' ';
buf[count - 2] = '\n';
@@ -1709,7 +1720,7 @@ cpp_define (pfile, str)
else
{
count = strlen (str) + 4;
- buf = alloca (count);
+ buf = (char *) alloca (count);
memcpy (buf, str, count - 4);
strcpy (&buf[count-4], " 1\n");
}
@@ -1729,7 +1740,7 @@ cpp_undef (pfile, macro)
{
/* Copy the string so we can append a newline. */
size_t len = strlen (macro);
- char *buf = alloca (len + 2);
+ char *buf = (char *) alloca (len + 2);
memcpy (buf, macro, len);
buf[len] = '\n';
buf[len + 1] = '\0';
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index 366196d686a..6e3561ac01b 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -32,36 +32,156 @@ typedef struct cpp_reader cpp_reader;
typedef struct cpp_buffer cpp_buffer;
typedef struct cpp_options cpp_options;
typedef struct cpp_printer cpp_printer;
-
+typedef struct cpp_token cpp_token;
+typedef struct cpp_toklist cpp_toklist;
+
+ /* Put operators that can appear in a preprocessor expression first.
+ This allows a lookup table to be implemented in _cpp_parse_expr.
+ Ordering within this group is currently not significant, apart
+ from those ending in '=' being at the end. */
+#define TTYPE_TABLE \
+ T(CPP_PLUS = 0, "+") /* math */ \
+ T(CPP_MINUS, "-") \
+ T(CPP_MULT, "*") \
+ T(CPP_DIV, "/") \
+ T(CPP_MOD, "%") \
+ T(CPP_AND, "&") /* bit ops */ \
+ T(CPP_OR, "|") \
+ T(CPP_XOR, "^") \
+ T(CPP_COMPL, "~") \
+ T(CPP_RSHIFT, ">>") \
+ T(CPP_LSHIFT, "<<") \
+ T(CPP_NOT, "!") /* logicals */ \
+ T(CPP_AND_AND, "&&") \
+ T(CPP_OR_OR, "||") \
+ T(CPP_QUERY, "?") \
+ T(CPP_COLON, ":") \
+ T(CPP_COMMA, ",") /* grouping */ \
+ T(CPP_OPEN_PAREN, "(") \
+ T(CPP_CLOSE_PAREN, ")") \
+ T(CPP_GREATER, ">") /* compare */ \
+ T(CPP_LESS, "<") \
+ T(CPP_EQ_EQ, "==") \
+ T(CPP_NOT_EQ, "!=") \
+ T(CPP_GREATER_EQ, ">=") \
+ T(CPP_LESS_EQ, "<=") \
+\
+ /* The remainder of the punctuation. Order is not significant. */ \
+ T(CPP_PLUS_EQ, "+=") /* math */ \
+ T(CPP_MINUS_EQ, "-=") \
+ T(CPP_MULT_EQ, "*=") \
+ T(CPP_DIV_EQ, "/=") \
+ T(CPP_MOD_EQ, "%=") \
+ T(CPP_AND_EQ, "&=") /* bit ops */ \
+ T(CPP_OR_EQ, "|=") \
+ T(CPP_XOR_EQ, "^=") \
+ T(CPP_COMPL_EQ, "~=") \
+ T(CPP_RSHIFT_EQ, ">>=") \
+ T(CPP_LSHIFT_EQ, "<<=") \
+ T(CPP_EQ, "=") /* assign */ \
+ T(CPP_PLUS_PLUS, "++") /* increment */ \
+ T(CPP_MINUS_MINUS, "--") \
+ T(CPP_DEREF, "->") /* accessors */ \
+ T(CPP_DOT, ".") \
+ T(CPP_OPEN_SQUARE, "[") \
+ T(CPP_CLOSE_SQUARE, "]") \
+ T(CPP_SCOPE, "::") \
+ T(CPP_DEREF_STAR, "->*") \
+ T(CPP_DOT_STAR, ".*") \
+ T(CPP_OPEN_BRACE, "{") /* structure */ \
+ T(CPP_CLOSE_BRACE, "}") \
+ T(CPP_SEMICOLON, ";") \
+ T(CPP_ELLIPSIS, "...") \
+ T(CPP_HASH, "#") \
+ T(CPP_PASTE, "##") \
+ T(CPP_BACKSLASH, "\\") \
+ T(CPP_MIN, "<?") /* extension */ \
+ T(CPP_MAX, ">?") \
+ T(CPP_OTHER, spell_other) /* stray punctuation */ \
+\
+ T(CPP_NAME, spell_name) /* word */ \
+ T(CPP_INT, 0) /* 23 */ \
+ T(CPP_FLOAT, 0) /* 3.14159 */ \
+ T(CPP_NUMBER, spell_name) /* 34_be+ta */ \
+ T(CPP_CHAR, spell_char) /* 'char' */ \
+ T(CPP_WCHAR, spell_char) /* L'char' */ \
+ T(CPP_STRING, spell_string) /* "string" */ \
+ T(CPP_WSTRING, spell_string) /* L"string" */ \
+\
+ T(CPP_COMMENT, spell_comment) /* Only if output comments. */ \
+ T(CPP_VSPACE, "\n") /* End of line. */ \
+ T(CPP_EOF, 0) /* End of file. */ \
+ T(CPP_HEADER_NAME, 0) /* <stdio.h> in #include */ \
+ T(CPP_ASSERTION, 0) /* (...) in #assert */ \
+\
+ /* Obsolete - will be removed when no code uses them still. */ \
+ T(CPP_HSPACE, 0) /* Horizontal white space. */ \
+ T(CPP_POP, 0) /* End of buffer. */ \
+ T(CPP_DIRECTIVE, 0) /* #define and the like */ \
+ T(CPP_MACRO, 0) /* Like a NAME, but expanded. */
+
+#define T(e, s) e,
enum cpp_ttype
{
- CPP_EOF = -1,
- CPP_OTHER = 0,
- CPP_COMMENT = 1,
- CPP_HSPACE,
- CPP_VSPACE, /* newlines and #line directives */
- CPP_NAME,
- CPP_MACRO,
- CPP_NUMBER,
- CPP_CHAR,
- CPP_WCHAR,
- CPP_STRING,
- CPP_WSTRING,
- CPP_DIRECTIVE,
- CPP_ASSERTION, /* #machine(a29k) */
- CPP_STRINGIZE, /* stringize macro argument */
- CPP_TOKPASTE, /* paste macro arg with next/prev token */
- CPP_LPAREN, /* "(" */
- CPP_RPAREN, /* ")" */
- CPP_LBRACE, /* "{" */
- CPP_RBRACE, /* "}" */
- CPP_COMMA, /* "," */
- CPP_SEMICOLON, /* ";" */
- CPP_3DOTS, /* "..." */
- CPP_POP /* We're about to pop the buffer stack. */
+ TTYPE_TABLE
+ N_TTYPES
+};
+#undef T
+
+/* Payload of a NAME, NUMBER, FLOAT, STRING, or COMMENT token. */
+struct cpp_name
+{
+ unsigned int len;
+ unsigned int offset; /* from list->namebuf */
+};
+
+/* A preprocessing token.
+ This has been carefully packed and should occupy 16 bytes on
+ both 32- and 64-bit hosts. */
+struct cpp_token
+{
+ unsigned short col; /* starting column of this token */
+#ifdef ENUM_BITFIELDS_ARE_UNSIGNED
+ enum cpp_ttype type : CHAR_BIT; /* node type */
+#else
+ unsigned char type;
+#endif
+ unsigned char flags; /* flags - not presently used */
+ unsigned int aux; /* hash of a NAME, or something -
+ see uses in the code */
+ union
+ {
+ struct cpp_name name; /* a string */
+ HOST_WIDEST_INT integer; /* an integer */
+ } val;
};
-typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *));
+/* Directive flags. */
+#define SYNTAX_INCLUDE (1 << 8)
+#define SYNTAX_ASSERT (1 << 9)
+
+typedef int (*directive_handler) PARAMS ((cpp_reader *));
+typedef int (*parse_cleanup_t) PARAMS ((cpp_buffer *, cpp_reader *));
+
+struct cpp_toklist
+{
+ struct cpp_token *tokens; /* actual tokens as an array */
+ unsigned int tokens_used; /* tokens used */
+ unsigned int tokens_cap; /* tokens allocated */
+
+ unsigned char *namebuf; /* names buffer */
+ unsigned int name_used; /* _bytes_ used */
+ unsigned int name_cap; /* _bytes_ allocated */
+
+ unsigned int line; /* starting line number */
+
+ /* Only used if tokens[0].type == CPP_DIRECTIVE. This is the
+ handler to call after lexing the rest of this line. The flags
+ indicate whether the rest of the line gets special treatment
+ during lexing (#include, #if, #assert, #unassert). */
+ directive_handler dir_handler;
+ unsigned short dir_flags;
+};
struct cpp_buffer
{
@@ -135,7 +255,7 @@ struct htab;
/* Values for opts.dump_macros.
dump_only means inhibit output of the preprocessed text
and instead output the definitions of all user-defined
- macros in a form suitable for use as input to cccp.
+ macros in a form suitable for use as input to cpp.
dump_names means pass #define and the macro name through to output.
dump_definitions means pass the whole definition (plus #define) through
*/
@@ -442,6 +562,8 @@ extern void cpp_reader_init PARAMS ((cpp_reader *));
extern cpp_printer *cpp_printer_init PARAMS ((cpp_reader *, cpp_printer *));
extern int cpp_start_read PARAMS ((cpp_reader *, cpp_printer *, const char *));
extern void cpp_output_tokens PARAMS ((cpp_reader *, cpp_printer *));
+extern void cpp_output_list PARAMS ((cpp_reader *, cpp_printer *,
+ const cpp_toklist *));
extern void cpp_finish PARAMS ((cpp_reader *, cpp_printer *));
extern void cpp_cleanup PARAMS ((cpp_reader *));
@@ -487,6 +609,8 @@ extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
extern void cpp_scan_buffer PARAMS ((cpp_reader *, cpp_printer *));
extern void cpp_scan_buffer_nooutput PARAMS ((cpp_reader *));
+
+
/* In cpphash.c */
extern int cpp_defined PARAMS ((cpp_reader *,
const unsigned char *, int));
diff --git a/gcc/cse.c b/gcc/cse.c
index 967c6f95e58..89b812d9951 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -705,6 +705,7 @@ static rtx cse_basic_block PARAMS ((rtx, rtx, struct branch_path *, int));
static void count_reg_usage PARAMS ((rtx, int *, rtx, int));
extern void dump_class PARAMS ((struct table_elt*));
static struct cse_reg_info * get_cse_reg_info PARAMS ((unsigned int));
+static int check_dependence PARAMS ((rtx *, void *));
static void flush_hash_table PARAMS ((void));
@@ -1721,6 +1722,24 @@ flush_hash_table ()
}
}
+/* Function called for each rtx to check whether true dependence exist. */
+struct check_dependence_data
+{
+ enum machine_mode mode;
+ rtx exp;
+};
+static int
+check_dependence (x, data)
+ rtx *x;
+ void *data;
+{
+ struct check_dependence_data *d = (struct check_dependence_data *) data;
+ if (*x && GET_CODE (*x) == MEM)
+ return true_dependence (d->exp, d->mode, *x, cse_rtx_varies_p);
+ else
+ return 0;
+}
+
/* Remove from the hash table, or mark as invalid, all expressions whose
values could be altered by storing in X. X is a register, a subreg, or
a memory reference with nonvarying address (because, when a memory
@@ -1846,20 +1865,18 @@ invalidate (x, full_mode)
next = p->next_same_hash;
if (p->in_memory)
{
- if (GET_CODE (p->exp) != MEM)
+ struct check_dependence_data d;
+
+ /* Just canonicalize the expression once;
+ otherwise each time we call invalidate
+ true_dependence will canonicalize the
+ expression again. */
+ if (!p->canon_exp)
+ p->canon_exp = canon_rtx (p->exp);
+ d.exp = x;
+ d.mode = full_mode;
+ if (for_each_rtx (&p->canon_exp, check_dependence, &d))
remove_from_table (p, i);
- else
- {
- /* Just canonicalize the expression once;
- otherwise each time we call invalidate
- true_dependence will canonicalize the
- expression again. */
- if (!p->canon_exp)
- p->canon_exp = canon_rtx (p->exp);
- if (true_dependence (x, full_mode, p->canon_exp,
- cse_rtx_varies_p))
- remove_from_table (p, i);
- }
}
}
}
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 0582c00c058..b551fea125f 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -80,7 +80,7 @@ do { ASM_OUTPUT_LABEL(FILE,LABEL_ALTERNATE_NAME (INSN)); } while (0)
register int c = p[i]; \
if (c == '\"' || c == '\\') \
putc ('\\', asm_out_file); \
- if (c >= ' ' && c < 0177) \
+ if (ISPRINT(c)) \
putc (c, asm_out_file); \
else \
{ \
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index c493d54f572..d5807877a70 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -144,13 +144,25 @@ dw_fde_node;
#ifndef CHAR_TYPE_SIZE
#define CHAR_TYPE_SIZE BITS_PER_UNIT
#endif
+
+/* The size of the target's pointer type. */
#ifndef PTR_SIZE
#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
#endif
+/* The size of addresses as they appear in the Dwarf 2 data.
+ Some architectures use word addresses to refer to code locations,
+ but Dwarf 2 info always uses byte addresses. On such machines,
+ Dwarf 2 addresses need to be larger than the architecture's
+ pointers. */
+#ifndef DWARF2_ADDR_SIZE
+#define DWARF2_ADDR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
+#endif
+
/* The size in bytes of a DWARF field indicating an offset or length
- relative to a debug info section, specified to be 4 bytes in the DWARF-2
- specification. The SGI/MIPS ABI defines it to be the same as PTR_SIZE. */
+ relative to a debug info section, specified to be 4 bytes in the
+ DWARF-2 specification. The SGI/MIPS ABI defines it to be the same
+ as PTR_SIZE. */
#ifndef DWARF_OFFSET_SIZE
#define DWARF_OFFSET_SIZE 4
@@ -164,9 +176,9 @@ dw_fde_node;
/* Offsets recorded in opcodes are a multiple of this alignment factor. */
#ifdef STACK_GROWS_DOWNWARD
-#define DWARF_CIE_DATA_ALIGNMENT (-UNITS_PER_WORD)
+#define DWARF_CIE_DATA_ALIGNMENT (-((int) UNITS_PER_WORD))
#else
-#define DWARF_CIE_DATA_ALIGNMENT UNITS_PER_WORD
+#define DWARF_CIE_DATA_ALIGNMENT ((int) UNITS_PER_WORD)
#endif
/* A pointer to the base of a table that contains frame description
@@ -312,9 +324,10 @@ static void dwarf2out_frame_debug_expr PARAMS ((rtx, char *));
#endif
#ifndef UNALIGNED_WORD_ASM_OP
-#define UNALIGNED_WORD_ASM_OP \
- ((PTR_SIZE) == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP : \
- ((PTR_SIZE) == 2 ? UNALIGNED_SHORT_ASM_OP : UNALIGNED_INT_ASM_OP))
+#define UNALIGNED_WORD_ASM_OP \
+ ((DWARF2_ADDR_SIZE) == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP \
+ : (DWARF2_ADDR_SIZE) == 2 ? UNALIGNED_SHORT_ASM_OP \
+ : UNALIGNED_INT_ASM_OP)
#endif
#ifndef ASM_OUTPUT_DWARF_DELTA2
@@ -426,7 +439,7 @@ static void dwarf2out_frame_debug_expr PARAMS ((rtx, char *));
.debug_frame. */
#define ASM_OUTPUT_DWARF_ADDR(FILE,LABEL) \
- assemble_integer (gen_rtx_SYMBOL_REF (Pmode, LABEL), PTR_SIZE, 1)
+ assemble_integer (gen_rtx_SYMBOL_REF (Pmode, LABEL), DWARF2_ADDR_SIZE, 1)
#define ASM_OUTPUT_DWARF_OFFSET4(FILE,LABEL) \
assemble_integer (gen_rtx_SYMBOL_REF (SImode, LABEL), 4, 1)
@@ -450,7 +463,7 @@ static void dwarf2out_frame_debug_expr PARAMS ((rtx, char *));
assemble_integer (gen_rtx_MINUS (Pmode, \
gen_rtx_SYMBOL_REF (Pmode, LABEL1), \
gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
- PTR_SIZE, 1)
+ DWARF2_ADDR_SIZE, 1)
#define ASM_OUTPUT_DWARF_DELTA(FILE,LABEL1,LABEL2) \
ASM_OUTPUT_DWARF_DELTA4 (FILE,LABEL1,LABEL2)
@@ -1640,7 +1653,7 @@ output_call_frame_info (for_eh)
tree label = get_file_function_name ('F');
force_data_section ();
- ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
+ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DWARF2_ADDR_SIZE));
ASM_GLOBALIZE_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
#endif
@@ -1744,7 +1757,7 @@ output_call_frame_info (for_eh)
output_cfi (cfi, NULL);
/* Pad the CIE out to an address sized boundary. */
- ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
+ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DWARF2_ADDR_SIZE));
ASM_OUTPUT_LABEL (asm_out_file, l2);
#ifdef ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL
ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL (asm_out_file, ld, l2, l1);
@@ -1816,7 +1829,7 @@ output_call_frame_info (for_eh)
output_cfi (cfi, fde);
/* Pad the FDE out to an address sized boundary. */
- ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
+ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DWARF2_ADDR_SIZE));
ASM_OUTPUT_LABEL (asm_out_file, l2);
#ifdef ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL
ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL (asm_out_file, ld, l2, l1);
@@ -2147,13 +2160,14 @@ extern int flag_traditional;
#define DWARF_PUBNAMES_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 2)
/* Fixed size portion of the address range info. */
-#define DWARF_ARANGES_HEADER_SIZE \
- (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, PTR_SIZE * 2) - DWARF_OFFSET_SIZE)
+#define DWARF_ARANGES_HEADER_SIZE \
+ (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, DWARF2_ADDR_SIZE * 2) \
+ - DWARF_OFFSET_SIZE)
/* Size of padding portion in the address range info. It must be
aligned to twice the pointer size. */
#define DWARF_ARANGES_PAD_SIZE \
- (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, PTR_SIZE * 2) \
+ (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, DWARF2_ADDR_SIZE * 2) \
- (2 * DWARF_OFFSET_SIZE + 4))
/* The default is to have gcc emit the line number tables. */
@@ -4460,7 +4474,7 @@ size_of_loc_descr (loc)
switch (loc->dw_loc_opc)
{
case DW_OP_addr:
- size += PTR_SIZE;
+ size += DWARF2_ADDR_SIZE;
break;
case DW_OP_const1u:
case DW_OP_const1s:
@@ -4601,7 +4615,7 @@ size_of_die (die)
switch (AT_class (a))
{
case dw_val_class_addr:
- size += PTR_SIZE;
+ size += DWARF2_ADDR_SIZE;
break;
case dw_val_class_loc:
{
@@ -4634,7 +4648,7 @@ size_of_die (die)
size += DWARF_OFFSET_SIZE;
break;
case dw_val_class_lbl_id:
- size += PTR_SIZE;
+ size += DWARF2_ADDR_SIZE;
break;
case dw_val_class_lbl_offset:
size += DWARF_OFFSET_SIZE;
@@ -4741,11 +4755,11 @@ size_of_aranges ()
size = DWARF_ARANGES_HEADER_SIZE;
/* Count the address/length pair for this compilation unit. */
- size += 2 * PTR_SIZE;
- size += 2 * PTR_SIZE * arange_table_in_use;
+ size += 2 * DWARF2_ADDR_SIZE;
+ size += 2 * DWARF2_ADDR_SIZE * arange_table_in_use;
/* Count the two zero words used to terminated the address range table. */
- size += 2 * PTR_SIZE;
+ size += 2 * DWARF2_ADDR_SIZE;
return size;
}
@@ -5212,7 +5226,7 @@ output_compilation_unit_header ()
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- ASM_OUTPUT_DWARF_DATA1 (asm_out_file, PTR_SIZE);
+ ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DWARF2_ADDR_SIZE);
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s Pointer Size (in bytes)", ASM_COMMENT_START);
@@ -5366,7 +5380,7 @@ output_aranges ()
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- ASM_OUTPUT_DWARF_DATA1 (asm_out_file, PTR_SIZE);
+ ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DWARF2_ADDR_SIZE);
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s Size of Address", ASM_COMMENT_START);
@@ -5388,7 +5402,7 @@ output_aranges ()
fprintf (asm_out_file, ",0");
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s Pad to %d byte boundary",
- ASM_COMMENT_START, 2 * PTR_SIZE);
+ ASM_COMMENT_START, 2 * DWARF2_ADDR_SIZE);
}
fputc ('\n', asm_out_file);
@@ -5632,13 +5646,14 @@ output_line_info ()
}
else
{
- /* This can handle any delta. This takes 4+PTR_SIZE bytes. */
+ /* This can handle any delta. This takes
+ 4+DWARF2_ADDR_SIZE bytes. */
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, 0);
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s DW_LNE_set_address",
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- output_uleb128 (1 + PTR_SIZE);
+ output_uleb128 (1 + DWARF2_ADDR_SIZE);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_set_address);
fputc ('\n', asm_out_file);
@@ -5730,7 +5745,7 @@ output_line_info ()
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s DW_LNE_set_address", ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- output_uleb128 (1 + PTR_SIZE);
+ output_uleb128 (1 + DWARF2_ADDR_SIZE);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_set_address);
fputc ('\n', asm_out_file);
@@ -5780,7 +5795,7 @@ output_line_info ()
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- output_uleb128 (1 + PTR_SIZE);
+ output_uleb128 (1 + DWARF2_ADDR_SIZE);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_set_address);
fputc ('\n', asm_out_file);
@@ -5809,7 +5824,7 @@ output_line_info ()
fprintf (asm_out_file, "\t%s DW_LNE_set_address",
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- output_uleb128 (1 + PTR_SIZE);
+ output_uleb128 (1 + DWARF2_ADDR_SIZE);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_set_address);
fputc ('\n', asm_out_file);
@@ -5911,7 +5926,7 @@ output_line_info ()
fprintf (asm_out_file, "\t%s DW_LNE_set_address",
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- output_uleb128 (1 + PTR_SIZE);
+ output_uleb128 (1 + DWARF2_ADDR_SIZE);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_set_address);
fputc ('\n', asm_out_file);
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 98009ec1ca1..9044fb56350 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -248,7 +248,8 @@ gen_rtx_CONST_INT (mode, arg)
#endif
/* Look up the CONST_INT in the hash table. */
- slot = htab_find_slot_with_hash (const_int_htab, &arg, (hashval_t) arg, 1);
+ slot = htab_find_slot_with_hash (const_int_htab, &arg,
+ (hashval_t) arg, INSERT);
if (*slot == 0)
{
if (!ggc_p)
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 16c9bef6b5f..bb06536e5e5 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -4181,6 +4181,29 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
break;
}
+ /* If we are comparing a double-word integer with zero, we can convert
+ the comparison into one involving a single word. */
+ if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD * 2
+ && GET_MODE_CLASS (mode) == MODE_INT
+ && op1 == const0_rtx)
+ {
+ if (code == EQ || code == NE)
+ {
+ /* Do a logical OR of the two words and compare the result. */
+ rtx op0h = gen_highpart (word_mode, op0);
+ rtx op0l = gen_lowpart (word_mode, op0);
+ rtx op0both = expand_binop (word_mode, ior_optab, op0h, op0l,
+ NULL_RTX, unsignedp, OPTAB_DIRECT);
+ if (op0both != 0)
+ return emit_store_flag (target, code, op0both, op1, word_mode,
+ unsignedp, normalizep);
+ }
+ else if (code == LT || code == GE)
+ /* If testing the sign bit, can just test on high word. */
+ return emit_store_flag (target, code, gen_highpart (word_mode, op0),
+ op1, word_mode, unsignedp, normalizep);
+ }
+
/* From now on, we won't change CODE, so set ICODE now. */
icode = setcc_gen_code[(int) code];
diff --git a/gcc/expr.h b/gcc/expr.h
index a349d9a32c8..8d7a9d8152c 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -894,7 +894,7 @@ extern rtx emit_store_flag_force PARAMS ((rtx, enum rtx_code, rtx, rtx,
/* Given an insn and condition, return a canonical description of
the test being made. */
-extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *));
+extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *, rtx));
/* Given a JUMP_INSN, return a canonical description of the test
being made. */
diff --git a/gcc/extend.texi b/gcc/extend.texi
index 22fe7414d2e..6d310ae0ca5 100644
--- a/gcc/extend.texi
+++ b/gcc/extend.texi
@@ -3199,7 +3199,9 @@ correspond to the C library functions @code{abort}, @code{abs},
@code{sinf}, @code{sinl}, @code{sqrt}, @code{sqrtf}, @code{sqrtl},
@code{strcmp}, @code{strcpy}, and @code{strlen}.
+@table @code
@findex __builtin_constant_p
+@item __builtin_constant_p (@var{exp})
You can use the builtin function @code{__builtin_constant_p} to
determine if a value is known to be constant at compile-time and hence
that GNU CC can perform constant-folding on expressions involving that
@@ -3228,6 +3230,39 @@ or constructor expression (@pxref{Constructors}) and will not return 1
when you pass a constant numeric value to the inline function unless you
specify the @samp{-O} option.
+@findex __builtin_expect
+@item __builtin_expect(@var{exp}, @var{c})
+You may use @code{__builtin_expect} to provide the compiler with
+branch prediction information. In general, you should prefer to
+use actual profile feedback for this (@samp{-fprofile-arcs}), as
+programmers are notoriously bad at predicting how their programs
+actually perform. However, there are applications in which this
+data is hard to collect.
+
+The return value is the value of @var{exp}, which should be an
+integral expression. The value of @var{c} must be a compile-time
+constant. The semantics of the builtin are that it is expected
+that @var{exp} == @var{c}. For example:
+
+@smallexample
+if (__builtin_expect (x, 0))
+ foo ();
+@end smallexample
+
+@noindent
+would indicate that we do not expect to call @code{foo}, since
+we expect @code{x} to be zero. Since you are limited to integral
+expressions for @var{exp}, you should use constructions such as
+
+@smallexample
+if (__builtin_expect (ptr != NULL, 1))
+ error ();
+@end smallexample
+
+@noindent
+when testing pointer or floating-point values.
+@end table
+
@node Deprecated Features
@section Deprecated Features
diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog
index cfe74fb4155..854802cf206 100644
--- a/gcc/f/ChangeLog
+++ b/gcc/f/ChangeLog
@@ -1,6 +1,11 @@
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lex.c: Remove references to cccp.c.
+ * g77install.texi: Remove references to cexp.c/cexp.y.
+
2000-04-15 David Edelsohn <edelsohn@gnu.org>
- * f/target.h (FFETARGET_32bit_longs): Define for 64-bit PowerPC
+ * target.h (FFETARGET_32bit_longs): Define for 64-bit PowerPC
as well.
Wed Apr 12 15:15:26 2000 Mark Mitchell <mark@codesourcery.com>
diff --git a/gcc/f/g77install.texi b/gcc/f/g77install.texi
index baa72ea76e7..67651a6db27 100644
--- a/gcc/f/g77install.texi
+++ b/gcc/f/g77install.texi
@@ -1992,7 +1992,7 @@ type these commands:
@example
sh# @kbd{cd gcc}
-sh# @kbd{touch bi-parser.c bi-parser.h c-parse.c c-parse.h cexp.c}
+sh# @kbd{touch bi-parser.c bi-parser.h c-parse.c c-parse.h}
sh# @kbd{touch cp/parse.c cp/parse.h objc-parse.c}
sh# @kbd{cd ..}
sh#
diff --git a/gcc/f/lex.c b/gcc/f/lex.c
index 0a5435c3753..a79bab37fee 100644
--- a/gcc/f/lex.c
+++ b/gcc/f/lex.c
@@ -1224,7 +1224,7 @@ ffelex_hash_ (FILE *finput)
&& getc (finput) == 't'
&& ((c = getc (finput)) == ' ' || c == '\t'))
{
- /* #ident. The pedantic warning is now in cccp.c. */
+ /* #ident. The pedantic warning is now in cpp. */
/* Here we have just seen `#ident '.
A string constant should follow. */
diff --git a/gcc/f/version.c b/gcc/f/version.c
index ea960e4c6f8..2a06a23af93 100644
--- a/gcc/f/version.c
+++ b/gcc/f/version.c
@@ -1 +1 @@
-const char *ffe_version_string = "0.5.25 20000415 (experimental)";
+const char *ffe_version_string = "0.5.25 20000420 (experimental)";
diff --git a/gcc/final.c b/gcc/final.c
index ade9da92964..1d4666ed764 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -3457,8 +3457,7 @@ output_asm_insn (template, operands)
Letters `acln' are implemented directly.
Other letters are passed to `output_operand' so that
the PRINT_OPERAND macro can define them. */
- else if ((*p >= 'a' && *p <= 'z')
- || (*p >= 'A' && *p <= 'Z'))
+ else if (ISLOWER(*p) || ISUPPER(*p))
{
int letter = *p++;
c = atoi (p);
diff --git a/gcc/fixinc/fixincl.c b/gcc/fixinc/fixincl.c
index fb5f68b22ea..a43ae3bd90f 100644
--- a/gcc/fixinc/fixincl.c
+++ b/gcc/fixinc/fixincl.c
@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
#include "fixlib.h"
-#if HAVE_MMAP
+#if HAVE_MMAP_FILE
#include <sys/mman.h>
#define BAD_ADDR ((void*)-1)
#endif
@@ -136,7 +136,7 @@ int fixed_ct = 0;
int altered_ct = 0;
#endif /* DO_STATS */
-#ifdef HAVE_MMAP
+#ifdef HAVE_MMAP_FILE
#define UNLOAD_DATA() do { if (curr_data_mapped) { \
munmap ((void*)pz_curr_data, data_map_size); close (data_map_fd); } \
else free ((void*)pz_curr_data); } while(0)
@@ -510,7 +510,7 @@ load_file ( fname )
return (char*)NULL;
}
-#ifdef HAVE_MMAP
+#ifdef HAVE_MMAP_FILE
curr_data_mapped = BOOL_TRUE;
res = (char*)mmap ((void*)NULL, data_map_size, PROT_READ, MAP_PRIVATE,
data_map_fd, 0);
diff --git a/gcc/fixproto b/gcc/fixproto
index 9e022113ea0..c2c82552a4b 100755
--- a/gcc/fixproto
+++ b/gcc/fixproto
@@ -264,6 +264,7 @@ for code in ALL STD ; do
then true
else
$FIX_HEADER $rel_source_file $abs_source_file $abs_target_file ${DEFINES} $include_path
+ if test $? != 0 ; then exit 1 ; fi
echo "${rel_source_file}" >>fixproto.list
fi
done
@@ -299,6 +300,7 @@ EOF
#endif /* __${rel_source_ident} */
EOF
${FIX_HEADER} $rel_source_file tmp.h $abs_target_dir/$rel_source_file ${DEFINES} $include_path
+ if test $? != 0 ; then exit 1 ; fi
rm tmp.h
fi
done
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 991dddda973..e0d0f00cb4e 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -106,6 +106,14 @@ static int count_cond PARAMS ((tree, int));
#define BRANCH_COST 1
#endif
+#if defined(HOST_EBCDIC)
+/* bit 8 is significant in EBCDIC */
+#define CHARMASK 0xff
+#else
+#define CHARMASK 0x7f
+#endif
+
+
/* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
overflow. Suppose A, B and SUM have the same respective signs as A1, B1,
and SUM1. Then this yields nonzero if overflow occurred during the
@@ -1091,8 +1099,8 @@ real_hex_to_f (s, mode)
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')
|| (c >= 'a' && c <= 'f'))
{
- k = c & 0x7f;
- if (k >= 'a')
+ k = c & CHARMASK;
+ if (k >= 'a' && k <= 'f')
k = k - 'a' + 10;
else if (k >= 'A')
k = k - 'A' + 10;
@@ -1137,7 +1145,7 @@ real_hex_to_f (s, mode)
The exponent field is a decimal integer. */
while (ISDIGIT(*p))
{
- k = (*p++ & 0x7f) - '0';
+ k = (*p++ & CHARMASK) - '0';
expon = 10 * expon + k;
}
diff --git a/gcc/function.c b/gcc/function.c
index 4b6f5ff1753..b502ab41f58 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -6182,13 +6182,8 @@ expand_function_start (subr, parms_have_cleanups)
else
/* Scalar, returned in a register. */
{
-#ifdef FUNCTION_OUTGOING_VALUE
- DECL_RTL (DECL_RESULT (subr))
- = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
-#else
DECL_RTL (DECL_RESULT (subr))
- = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
-#endif
+ = hard_function_value (TREE_TYPE (DECL_RESULT (subr)), subr, 1);
/* Mark this reg as the function's return value. */
if (GET_CODE (DECL_RTL (DECL_RESULT (subr))) == REG)
diff --git a/gcc/gengenrtl.c b/gcc/gengenrtl.c
index 2eec4592699..1519914edf0 100644
--- a/gcc/gengenrtl.c
+++ b/gcc/gengenrtl.c
@@ -324,7 +324,7 @@ gendef (format)
static void
genlegend ()
{
- printf ("/* Generated automaticaly by the program `gengenrtl'\n");
+ printf ("/* Generated automatically by the program `gengenrtl'\n");
printf (" from the RTL description file `rtl.def' */\n\n");
}
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 88488fec445..9fafd22204e 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -91,7 +91,7 @@ ggc_add_rtx_root (base, nelt)
rtx *base;
int nelt;
{
- ggc_add_root (base, nelt, sizeof(rtx), ggc_mark_rtx_ptr);
+ ggc_add_root (base, nelt, sizeof (rtx), ggc_mark_rtx_ptr);
}
/* Register an array of trees as a GC root. */
@@ -101,7 +101,7 @@ ggc_add_tree_root (base, nelt)
tree *base;
int nelt;
{
- ggc_add_root (base, nelt, sizeof(tree), ggc_mark_tree_ptr);
+ ggc_add_root (base, nelt, sizeof (tree), ggc_mark_tree_ptr);
}
/* Register a varray of rtxs as a GC root. */
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 43f53abedf2..e75fb74b730 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -4,22 +4,22 @@
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
- This file is part of GNU CC.
-
- GNU CC 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.
-
- GNU CC 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 GNU CC; see the file COPYING. If not, write to the Free
- the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to the Free
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
/* Instruction scheduling pass.
diff --git a/gcc/install.texi b/gcc/install.texi
index 5c31cb20f2b..1e660a818a2 100644
--- a/gcc/install.texi
+++ b/gcc/install.texi
@@ -53,10 +53,9 @@ On a System V release 4 system, make sure @file{/usr/bin} precedes
@cindex Bison parser generator
@cindex parser generator, Bison
@item
-Make sure the Bison parser generator is installed. (This is
-unnecessary if the Bison output files @file{c-parse.c} and
-@file{cexp.c} are more recent than @file{c-parse.y} and @file{cexp.y}
-and you do not plan to change the @samp{.y} files.)
+Make sure the Bison parser generator is installed. (This is unnecessary
+if the Bison output file @file{c-parse.c} is more recent than
+@file{c-parse.y},and you do not plan to change the @samp{.y} file.)
Bison versions older than Sept 8, 1988 will produce incorrect output
for @file{c-parse.c}.
@@ -396,9 +395,8 @@ Ignore any warnings you may see about ``statement not reached'' in
escape sequence'' are normal in @file{genopinit.c} and perhaps some
other files. Likewise, you should ignore warnings about ``constant is
so large that it is unsigned'' in @file{insn-emit.c} and
-@file{insn-recog.c}, a warning about a comparison always being zero
-in @file{enquire.o}, and warnings about shift counts exceeding type
-widths in @file{cexp.y}. Any other compilation errors may represent bugs in
+@file{insn-recog.c}, and a warning about a comparison always being zero
+in @file{enquire.o}. Any other compilation errors may represent bugs in
the port to your machine or operating system, and
@ifclear INSTALLONLY
should be investigated and reported (@pxref{Bugs}).
@@ -1260,47 +1258,11 @@ You will also a patched version of @file{/bin/ld} there that
raises some of the arbitrary limits found in the original.
@item m68k-att-sysv
-AT&T 3b1, a.k.a. 7300 PC. Special procedures are needed to compile GNU
-CC with this machine's standard C compiler, due to bugs in that
-compiler. You can bootstrap it more easily with
-previous versions of GNU CC if you have them.
-
-Installing GNU CC on the 3b1 is difficult if you do not already have
-GNU CC running, due to bugs in the installed C compiler. However,
-the following procedure might work. We are unable to test it.
-
-@enumerate
-@item
-Comment out the @samp{#include "config.h"} line near the start of
-@file{cccp.c} and do @samp{make cpp}. This makes a preliminary version
-of GNU cpp.
-
-@item
-Save the old @file{/lib/cpp} and copy the preliminary GNU cpp to that
-file name.
-
-@item
-Undo your change in @file{cccp.c}, or reinstall the original version,
-and do @samp{make cpp} again.
-
-@item
-Copy this final version of GNU cpp into @file{/lib/cpp}.
-
-@findex obstack_free
-@item
-Replace every occurrence of @code{obstack_free} in the file
-@file{tree.c} with @code{_obstack_free}.
-
-@item
-Run @code{make} to get the first-stage GNU CC.
-
-@item
-Reinstall the original version of @file{/lib/cpp}.
-
-@item
-Now you can compile GNU CC with itself and install it in the normal
-fashion.
-@end enumerate
+AT&T 3b1, a.k.a. 7300 PC. This version of GNU CC cannot
+be compiled with the system C compiler, which is too buggy.
+You will need to get a previous version of GCC and use it to
+bootstrap. Binaries are available from the OSU-CIS archive, at
+@url{ftp://archive.cis.ohio-state.edu/pub/att7300/}.
@item m68k-bull-sysv
Bull DPX/2 series 200 and 300 with BOS-2.00.45 up to BOS-2.01. GNU CC works
diff --git a/gcc/intl/loadmsgcat.c b/gcc/intl/loadmsgcat.c
index 515892dfb86..4dfb687b9f0 100644
--- a/gcc/intl/loadmsgcat.c
+++ b/gcc/intl/loadmsgcat.c
@@ -31,7 +31,7 @@
# include <unistd.h>
#endif
-#if (defined HAVE_MMAP && defined HAVE_MUNMAP) || defined _LIBC
+#if defined HAVE_MMAP_FILE || defined _LIBC
# include <sys/mman.h>
#endif
@@ -68,7 +68,7 @@ _nl_load_domain (domain_file)
size_t size;
struct stat st;
struct mo_file_header *data = (struct mo_file_header *) -1;
-#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+#if (defined HAVE_MMAP_FILE && !defined DISALLOW_MMAP) \
|| defined _LIBC
int use_mmap = 0;
#endif
@@ -99,7 +99,7 @@ _nl_load_domain (domain_file)
return;
}
-#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+#if (defined HAVE_MMAP_FILE && !defined DISALLOW_MMAP) \
|| defined _LIBC
/* Now we are ready to load the file. If mmap() is available we try
this first. If not available or it failed we try to load it. */
@@ -149,7 +149,7 @@ _nl_load_domain (domain_file)
if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED)
{
/* The magic number is wrong: not a message catalog file. */
-#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+#if (defined HAVE_MMAP_FILE && !defined DISALLOW_MMAP) \
|| defined _LIBC
if (use_mmap)
munmap ((caddr_t) data, size);
@@ -166,7 +166,7 @@ _nl_load_domain (domain_file)
domain = (struct loaded_domain *) domain_file->data;
domain->data = (char *) data;
-#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+#if (defined HAVE_MMAP_FILE && !defined DISALLOW_MMAP) \
|| defined _LIBC
domain->use_mmap = use_mmap;
#endif
@@ -188,7 +188,7 @@ _nl_load_domain (domain_file)
break;
default:
/* This is an illegal revision. */
-#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+#if (defined HAVE_MMAP_FILE && !defined DISALLOW_MMAP) \
|| defined _LIBC
if (use_mmap)
munmap ((caddr_t) data, size);
diff --git a/gcc/invoke.texi b/gcc/invoke.texi
index 6638839039e..3e13098dfb6 100644
--- a/gcc/invoke.texi
+++ b/gcc/invoke.texi
@@ -2201,51 +2201,64 @@ Here are the possible letters for use in @var{letters}, and their meanings:
@item A
Annotate the assembler output with miscellaneous debugging information.
@item b
-Dump after computing branch probabilities, to @file{@var{file}.07.bp}.
+Dump after computing branch probabilities, to @file{@var{file}.10.bp}.
+@item B
+Dump after block reordering, to @file{@var{file}.20.bbro}.
@item c
-Dump after instruction combination, to the file @file{@var{file}.09.combine}.
+Dump after instruction combination, to the file @file{@var{file}.12.combine}.
@item d
-Dump after delayed branch scheduling, to @file{@var{file}.19.dbr}.
+Dump after delayed branch scheduling, to @file{@var{file}.24.dbr}.
@item D
Dump all macro definitions, at the end of preprocessing, in addition to
normal output.
-@item F
-Dump after purging ADDRESSOF, to @file{@var{file}.03.addressof}.
+@item e
+Dump after SSA optimizations, to @file{@var{file}.05.ssa} and
+@file{@var{file}.06.ussa}.
@item f
-Dump after flow analysis, to @file{@var{file}.08.flow}.
+Dump after flow analysis, to @file{@var{file}.11.flow}.
+@item F
+Dump after purging @code{ADDRESSOF} codes, to @file{@var{file}.04.addressof}.
@item g
-Dump after global register allocation, to @file{@var{file}.13.greg}.
+Dump after global register allocation, to @file{@var{file}.16.greg}.
@item G
-Dump after GCSE, to @file{@var{file}.04.gcse}.
+Dump after GCSE, to @file{@var{file}.07.gcse}.
+@item i
+Dump after sibling call optimizations, to @file{@var{file}.01.sibling}.
@item j
-Dump after first jump optimization, to @file{@var{file}.01.jump}.
+Dump after first jump optimization, to @file{@var{file}.02.jump}.
@item J
-Dump after last jump optimization, to @file{@var{file}.17.jump2}.
+Dump after last jump optimization, to @file{@var{file}.22.jump2}.
@item k
-Dump after conversion from registers to stack, to @file{@var{file}.20.stack}.
+Dump after conversion from registers to stack, to @file{@var{file}.25.stack}.
@item l
-Dump after local register allocation, to @file{@var{file}.12.lreg}.
+Dump after local register allocation, to @file{@var{file}.15.lreg}.
@item L
-Dump after loop optimization, to @file{@var{file}.05.loop}.
+Dump after loop optimization, to @file{@var{file}.08.loop}.
@item M
Dump after performing the machine dependent reorganisation pass, to
-@file{@var{file}.18.mach}.
+@file{@var{file}.23.mach}.
+@item n
+Dump after register renumbering, to @file{@var{file}.21.rnreg}.
@item N
-Dump after the register move pass, to @file{@var{file}.10.regmove}.
+Dump after the register move pass, to @file{@var{file}.13.regmove}.
@item r
Dump after RTL generation, to @file{@var{file}.00.rtl}.
@item R
Dump after the second instruction scheduling pass, to
-@file{@var{file}.16.sched2}.
+@file{@var{file}.19.sched2}.
@item s
Dump after CSE (including the jump optimization that sometimes follows
-CSE), to @file{@var{file}.02.cse}.
+CSE), to @file{@var{file}.03.cse}.
@item S
Dump after the first instruction scheduling pass, to
-@file{@var{file}.11.sched}.
+@file{@var{file}.14.sched}.
@item t
Dump after the second CSE pass (including the jump optimization that
-sometimes follows CSE), to @file{@var{file}.06.cse2}.
+sometimes follows CSE), to @file{@var{file}.09.cse2}.
+@item w
+Dump after the second flow pass, to @file{@var{file}.17.flow2}.
+@item z
+Dump after the peephold pass, to @file{@var{file}.18.peephole2}.
@item a
Produce all the dumps listed above.
@item m
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 8123c230f75..8d2ba834b24 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,47 @@
+2000-04-19 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (yyerror): `msg' can be null, don't use it in that case.
+
+2000-04-19 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (cxx_keyword_subst): Avoid potential infinite loop.
+
+2000-04-18 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (maybe_make_nested_class_name): Use `obstack_grow0'.
+
+2000-04-18 Tom Tromey <tromey@cygnus.com>
+
+ PR gcj/211:
+ * gjavah.c (utf8_cmp): Changed return value.
+ (cxx_keyword_subst): Handle all C++ keywords. Allocate new return
+ result.
+ (cxx_keywords): New global.
+ (get_field_name): Handle new result of cxx_keyword_subst.
+ (print_method_info): Likewise.
+
+2000-04-17 Bryce McKinlay <bryce@albatross.co.nz>
+
+ * gjavah.c (print_name_for_stub_or_jni): Don't prefix method names
+ with a newline, for CNI.
+ (print_stub_or_jni): Print a space or newline before method name for
+ CNI as well as JNI.
+ (print_cxx_classname): Don't write leading "::" in CNI stub method.
+ (process_file): Include gcj/cni.h if generating CNI stubs.
+
+2000-04-16 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (decompile_method): Use print_field_name.
+ Fixes PR gcj/205.
+
+2000-04-14 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse.y (java_expand_classes): Reverse the package list once.
+ (java_complete_lhs): PLUS_EXPR: don't try rhs and lhs at string
+ reduction.
+ (patch_binop): New temp `cn'. Call patch_string on LHS/RHS of
+ the `==' and `!=' operators.
+
2000-04-05 Tom Tromey <tromey@cygnus.com>
Fix for PR gcj/140:
diff --git a/gcc/java/gjavah.c b/gcc/java/gjavah.c
index 4c36e879319..4c6d81de543 100644
--- a/gcc/java/gjavah.c
+++ b/gcc/java/gjavah.c
@@ -131,7 +131,7 @@ static int java_double_finite PARAMS ((jdouble));
static void print_name PARAMS ((FILE *, JCF *, int));
static void print_base_classname PARAMS ((FILE *, JCF *, int));
static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
-static const char *cxx_keyword_subst PARAMS ((const unsigned char *, int));
+static char *cxx_keyword_subst PARAMS ((const unsigned char *, int));
static void generate_access PARAMS ((FILE *, JCF_u2));
static int name_is_method_p PARAMS ((const unsigned char *, int));
static char *get_field_name PARAMS ((JCF *, int, JCF_u2));
@@ -336,7 +336,8 @@ print_base_classname (stream, jcf, index)
}
}
-/* Return 0 if NAME is equal to STR, nonzero otherwise. */
+/* Return 0 if NAME is equal to STR, -1 if STR is "less" than NAME,
+ and 1 if STR is "greater" than NAME. */
static int
utf8_cmp (str, length, name)
@@ -351,26 +352,82 @@ utf8_cmp (str, length, name)
{
int ch = UTF8_GET (str, limit);
if (ch != name[i])
- return 1;
+ return ch - name[i];
}
- return str != limit;
+ return str == limit ? 0 : 1;
}
+/* This is a sorted list of all C++ keywords. */
+
+static const char *cxx_keywords[] =
+{
+ "asm",
+ "auto",
+ "bool",
+ "const_cast",
+ "delete",
+ "dynamic_cast",
+ "enum",
+ "explicit",
+ "extern",
+ "friend",
+ "inline",
+ "mutable",
+ "namespace",
+ "overload",
+ "register",
+ "reinterpret_cast",
+ "signed",
+ "sizeof",
+ "static_cast",
+ "struct",
+ "template",
+ "typedef",
+ "typeid",
+ "typename",
+ "typenameopt",
+ "union",
+ "unsigned",
+ "using",
+ "virtual",
+ "volatile",
+ "wchar_t"
+};
+
+
/* If NAME is the name of a C++ keyword, then return an override name.
This is a name that can be used in place of the keyword.
- Otherwise, return NULL. FIXME: for now, we only handle those
- keywords we know to be a problem for libgcj. */
+ Otherwise, return NULL. The return value is malloc()d. */
-static const char *
+static char *
cxx_keyword_subst (str, length)
const unsigned char *str;
int length;
{
- if (! utf8_cmp (str, length, "delete"))
- return "__dummy_delete";
- else if (! utf8_cmp (str, length, "enum"))
- return "__dummy_enum";
+ int last = sizeof (cxx_keywords) / sizeof (const char *);
+ int first = 0;
+ int mid = (last + first) / 2;
+ int old = -1;
+
+ for (mid = (last + first) / 2;
+ mid != old;
+ old = mid, mid = (last + first) / 2)
+ {
+ int r = utf8_cmp (str, length, cxx_keywords[mid]);
+
+ if (r == 0)
+ {
+ char *str = xmalloc (9 + strlen (cxx_keywords[mid]));
+ strcpy (str, "__dummy_");
+ strcat (str, cxx_keywords[mid]);
+ return str;
+ }
+ else if (r < 0)
+ last = mid;
+ else
+ first = mid;
+ }
return NULL;
}
@@ -455,8 +512,6 @@ get_field_name (jcf, name_index, flags)
unsigned char *name = JPOOL_UTF_DATA (jcf, name_index);
int length = JPOOL_UTF_LENGTH (jcf, name_index);
char *override;
- const char *tmpconstptr;
-
if (name_is_method_p (name, length))
{
@@ -475,14 +530,9 @@ get_field_name (jcf, name_index, flags)
memcpy (override, name, length);
strcpy (override + length, "__");
}
- else if ((tmpconstptr = cxx_keyword_subst (name, length)) != NULL)
- {
- /* Must malloc OVERRIDE. */
- override = xstrdup (tmpconstptr);
- }
else
- override = NULL;
-
+ override = cxx_keyword_subst (name, length);
+
return override;
}
@@ -622,7 +672,7 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
{
const unsigned char *str;
int length, is_init = 0;
- const char *override = NULL;
+ char *override = NULL;
method_declared = 0;
method_access = flags;
@@ -688,7 +738,10 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
mangling will be wrong. FIXME. */
if (METHOD_IS_FINAL (jcf->access_flags, flags)
|| (flags & ACC_STATIC))
- return;
+ {
+ free (override);
+ return;
+ }
}
}
@@ -723,6 +776,9 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
is_init, override, flags);
}
}
+
+ if (override)
+ free (override);
}
/* Try to decompile a method body. Right now we just try to handle a
@@ -758,7 +814,8 @@ decompile_method (out, jcf, code_len)
name_and_type = JPOOL_USHORT2 (jcf, index);
/* FIXME: ensure that tag is CONSTANT_NameAndType. */
name = JPOOL_USHORT1 (jcf, name_and_type);
- print_name (out, jcf, name);
+ /* FIXME: flags. */
+ print_field_name (out, jcf, name, 0);
fputs ("; }", out);
decompiled = 1;
}
@@ -1122,7 +1179,7 @@ DEFUN (print_name_for_stub_or_jni, (stream, jcf, name_index, signature_index,
AND int name_index AND int signature_index
AND int is_init AND const char *name_override AND int flags)
{
- const char *const prefix = flag_jni ? "Java_" : "\n";
+ const char *const prefix = flag_jni ? "Java_" : "";
print_cxx_classname (stream, prefix, jcf, jcf->this_class);
fputs (flag_jni ? "_" : "::", stream);
print_full_cxx_name (stream, jcf, name_index,
@@ -1188,9 +1245,8 @@ DEFUN(print_stub_or_jni, (stream, jcf, name_index, signature_index, is_init,
/* When printing a JNI header we need to respect the space. In
other cases we're just going to insert a newline anyway. */
- if (flag_jni)
- fputs (need_space && ! stubs ? " " : "\n", stream);
-
+ fputs (need_space && ! stubs ? " " : "\n", stream);
+
/* Now print the name of the thing. */
print_name_for_stub_or_jni (stream, jcf, name_index,
signature_index, is_init, name_override,
@@ -1251,7 +1307,7 @@ print_cxx_classname (stream, prefix, jcf, index)
fputs (prefix, stream);
/* Print a leading "::" so we look in the right namespace. */
- if (! flag_jni)
+ if (! flag_jni && ! stubs)
fputs ("::", stream);
while (s < limit)
@@ -1691,6 +1747,7 @@ DEFUN(process_file, (jcf, out),
if (len > 6 && ! strcmp (&jcf->classname[len - 6], ".class"))
len -= 6;
print_include (out, jcf->classname, len);
+ print_include (out, "gcj/cni", -1);
}
}
diff --git a/gcc/java/parse.c b/gcc/java/parse.c
index f65e21fccf1..ac7bdac1493 100644
--- a/gcc/java/parse.c
+++ b/gcc/java/parse.c
@@ -1,7 +1,6 @@
/* A Bison parser, made from ./parse.y
- by GNU Bison version 1.25
- */
+ by GNU Bison version 1.28 */
#define YYBISON 1 /* Identify Bison output. */
@@ -12,113 +11,113 @@
#define yychar java_char
#define yydebug java_debug
#define yynerrs java_nerrs
-#define PLUS_TK 258
-#define MINUS_TK 259
-#define MULT_TK 260
-#define DIV_TK 261
-#define REM_TK 262
-#define LS_TK 263
-#define SRS_TK 264
-#define ZRS_TK 265
-#define AND_TK 266
-#define XOR_TK 267
-#define OR_TK 268
-#define BOOL_AND_TK 269
-#define BOOL_OR_TK 270
-#define EQ_TK 271
-#define NEQ_TK 272
-#define GT_TK 273
-#define GTE_TK 274
-#define LT_TK 275
-#define LTE_TK 276
-#define PLUS_ASSIGN_TK 277
-#define MINUS_ASSIGN_TK 278
-#define MULT_ASSIGN_TK 279
-#define DIV_ASSIGN_TK 280
-#define REM_ASSIGN_TK 281
-#define LS_ASSIGN_TK 282
-#define SRS_ASSIGN_TK 283
-#define ZRS_ASSIGN_TK 284
-#define AND_ASSIGN_TK 285
-#define XOR_ASSIGN_TK 286
-#define OR_ASSIGN_TK 287
-#define PUBLIC_TK 288
-#define PRIVATE_TK 289
-#define PROTECTED_TK 290
-#define STATIC_TK 291
-#define FINAL_TK 292
-#define SYNCHRONIZED_TK 293
-#define VOLATILE_TK 294
-#define TRANSIENT_TK 295
-#define NATIVE_TK 296
-#define PAD_TK 297
-#define ABSTRACT_TK 298
-#define MODIFIER_TK 299
-#define DECR_TK 300
-#define INCR_TK 301
-#define DEFAULT_TK 302
-#define IF_TK 303
-#define THROW_TK 304
-#define BOOLEAN_TK 305
-#define DO_TK 306
-#define IMPLEMENTS_TK 307
-#define THROWS_TK 308
-#define BREAK_TK 309
-#define IMPORT_TK 310
-#define ELSE_TK 311
-#define INSTANCEOF_TK 312
-#define RETURN_TK 313
-#define VOID_TK 314
-#define CATCH_TK 315
-#define INTERFACE_TK 316
-#define CASE_TK 317
-#define EXTENDS_TK 318
-#define FINALLY_TK 319
-#define SUPER_TK 320
-#define WHILE_TK 321
-#define CLASS_TK 322
-#define SWITCH_TK 323
-#define CONST_TK 324
-#define TRY_TK 325
-#define FOR_TK 326
-#define NEW_TK 327
-#define CONTINUE_TK 328
-#define GOTO_TK 329
-#define PACKAGE_TK 330
-#define THIS_TK 331
-#define BYTE_TK 332
-#define SHORT_TK 333
-#define INT_TK 334
-#define LONG_TK 335
-#define CHAR_TK 336
-#define INTEGRAL_TK 337
-#define FLOAT_TK 338
-#define DOUBLE_TK 339
-#define FP_TK 340
-#define ID_TK 341
-#define REL_QM_TK 342
-#define REL_CL_TK 343
-#define NOT_TK 344
-#define NEG_TK 345
-#define ASSIGN_ANY_TK 346
-#define ASSIGN_TK 347
-#define OP_TK 348
-#define CP_TK 349
-#define OCB_TK 350
-#define CCB_TK 351
-#define OSB_TK 352
-#define CSB_TK 353
-#define SC_TK 354
-#define C_TK 355
-#define DOT_TK 356
-#define STRING_LIT_TK 357
-#define CHAR_LIT_TK 358
-#define INT_LIT_TK 359
-#define FP_LIT_TK 360
-#define TRUE_TK 361
-#define FALSE_TK 362
-#define BOOL_LIT_TK 363
-#define NULL_TK 364
+#define PLUS_TK 257
+#define MINUS_TK 258
+#define MULT_TK 259
+#define DIV_TK 260
+#define REM_TK 261
+#define LS_TK 262
+#define SRS_TK 263
+#define ZRS_TK 264
+#define AND_TK 265
+#define XOR_TK 266
+#define OR_TK 267
+#define BOOL_AND_TK 268
+#define BOOL_OR_TK 269
+#define EQ_TK 270
+#define NEQ_TK 271
+#define GT_TK 272
+#define GTE_TK 273
+#define LT_TK 274
+#define LTE_TK 275
+#define PLUS_ASSIGN_TK 276
+#define MINUS_ASSIGN_TK 277
+#define MULT_ASSIGN_TK 278
+#define DIV_ASSIGN_TK 279
+#define REM_ASSIGN_TK 280
+#define LS_ASSIGN_TK 281
+#define SRS_ASSIGN_TK 282
+#define ZRS_ASSIGN_TK 283
+#define AND_ASSIGN_TK 284
+#define XOR_ASSIGN_TK 285
+#define OR_ASSIGN_TK 286
+#define PUBLIC_TK 287
+#define PRIVATE_TK 288
+#define PROTECTED_TK 289
+#define STATIC_TK 290
+#define FINAL_TK 291
+#define SYNCHRONIZED_TK 292
+#define VOLATILE_TK 293
+#define TRANSIENT_TK 294
+#define NATIVE_TK 295
+#define PAD_TK 296
+#define ABSTRACT_TK 297
+#define MODIFIER_TK 298
+#define DECR_TK 299
+#define INCR_TK 300
+#define DEFAULT_TK 301
+#define IF_TK 302
+#define THROW_TK 303
+#define BOOLEAN_TK 304
+#define DO_TK 305
+#define IMPLEMENTS_TK 306
+#define THROWS_TK 307
+#define BREAK_TK 308
+#define IMPORT_TK 309
+#define ELSE_TK 310
+#define INSTANCEOF_TK 311
+#define RETURN_TK 312
+#define VOID_TK 313
+#define CATCH_TK 314
+#define INTERFACE_TK 315
+#define CASE_TK 316
+#define EXTENDS_TK 317
+#define FINALLY_TK 318
+#define SUPER_TK 319
+#define WHILE_TK 320
+#define CLASS_TK 321
+#define SWITCH_TK 322
+#define CONST_TK 323
+#define TRY_TK 324
+#define FOR_TK 325
+#define NEW_TK 326
+#define CONTINUE_TK 327
+#define GOTO_TK 328
+#define PACKAGE_TK 329
+#define THIS_TK 330
+#define BYTE_TK 331
+#define SHORT_TK 332
+#define INT_TK 333
+#define LONG_TK 334
+#define CHAR_TK 335
+#define INTEGRAL_TK 336
+#define FLOAT_TK 337
+#define DOUBLE_TK 338
+#define FP_TK 339
+#define ID_TK 340
+#define REL_QM_TK 341
+#define REL_CL_TK 342
+#define NOT_TK 343
+#define NEG_TK 344
+#define ASSIGN_ANY_TK 345
+#define ASSIGN_TK 346
+#define OP_TK 347
+#define CP_TK 348
+#define OCB_TK 349
+#define CCB_TK 350
+#define OSB_TK 351
+#define CSB_TK 352
+#define SC_TK 353
+#define C_TK 354
+#define DOT_TK 355
+#define STRING_LIT_TK 356
+#define CHAR_LIT_TK 357
+#define INT_LIT_TK 358
+#define FP_LIT_TK 359
+#define TRUE_TK 360
+#define FALSE_TK 361
+#define BOOL_LIT_TK 362
+#define NULL_TK 363
#line 48 "./parse.y"
@@ -517,7 +516,7 @@ typedef union {
#define YYFLAG -32768
#define YYNTBASE 110
-#define YYTRANSLATE(x) ((unsigned)(x) <= 364 ? yytranslate[x] : 272)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 363 ? yytranslate[x] : 272)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -545,18 +544,18 @@ static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
- 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
- 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
- 106, 107, 108, 109
+ 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109
};
#if YYDEBUG != 0
@@ -2387,7 +2386,8 @@ static const short yycheck[] = { 3,
#define YYPURE 1
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/share/misc/bison.simple"
+#line 3 "/usr/lib/bison.simple"
+/* This file comes from bison-1.28. */
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -2404,46 +2404,66 @@ static const short yycheck[] = { 3,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
-#ifndef alloca
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+#ifndef YYSTACK_USE_ALLOCA
+#ifdef alloca
+#define YYSTACK_USE_ALLOCA
+#else /* alloca not defined */
#ifdef __GNUC__
+#define YYSTACK_USE_ALLOCA
#define alloca __builtin_alloca
#else /* not GNU C. */
-#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
+#define YYSTACK_USE_ALLOCA
#include <alloca.h>
#else /* not sparc */
-#if defined (MSDOS) && !defined (__TURBOC__)
+/* We think this test detects Watcom and Microsoft C. */
+/* This used to test MSDOS, but that is a bad idea
+ since that symbol is in the user namespace. */
+#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
+#if 0 /* No need for malloc.h, which pollutes the namespace;
+ instead, just don't use alloca. */
#include <malloc.h>
+#endif
#else /* not MSDOS, or __TURBOC__ */
#if defined(_AIX)
-#include <malloc.h>
+/* I don't know what this was needed for, but it pollutes the namespace.
+ So I turned it off. rms, 2 May 1997. */
+/* #include <malloc.h> */
#pragma alloca
-#else /* not MSDOS, __TURBOC__, or _AIX */
-#ifdef __hpux
-#ifdef __cplusplus
-extern "C" {
-void *alloca (unsigned int);
-};
-#else /* not __cplusplus */
-void *alloca ();
-#endif /* not __cplusplus */
+#define YYSTACK_USE_ALLOCA
+#else /* not MSDOS, or __TURBOC__, or _AIX */
+#if 0
+#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
+ and on HPUX 10. Eventually we can turn this on. */
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
#endif /* __hpux */
+#endif
#endif /* not _AIX */
#endif /* not MSDOS, or __TURBOC__ */
-#endif /* not sparc. */
-#endif /* not GNU C. */
-#endif /* alloca not defined. */
+#endif /* not sparc */
+#endif /* not GNU C */
+#endif /* alloca not defined */
+#endif /* YYSTACK_USE_ALLOCA not defined */
-/* This is the parser code that is written into each bison parser
- when the %semantic_parser declaration is not specified in the grammar.
- It was written by Richard Stallman by simplifying the hairy parser
- used when %semantic_parser is specified. */
+#ifdef YYSTACK_USE_ALLOCA
+#define YYSTACK_ALLOC alloca
+#else
+#define YYSTACK_ALLOC malloc
+#endif
/* Note: there must be only one dollar sign in this file.
It is replaced by the list of actions, each action
@@ -2453,8 +2473,8 @@ void *alloca ();
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
-#define YYACCEPT return(0)
-#define YYABORT return(1)
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
#define YYERROR goto yyerrlab1
/* Like YYERROR except do call yyerror.
This remains here temporarily to ease the
@@ -2535,14 +2555,12 @@ int yydebug; /* nonzero means print parse trace */
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 10000
#endif
-
-/* Prevent warning if -Wstrict-prototypes. */
-#ifdef __GNUC__
-#ifndef YYPARSE_PARAM
-int yyparse (void);
-#endif
-#endif
+/* Define __yy_memcpy. Note that the size argument
+ should be passed with type unsigned int, because that is what the non-GCC
+ definitions require. With GCC, __builtin_memcpy takes an arg
+ of type size_t, but it can handle unsigned int. */
+
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
#else /* not GNU C or C++ */
@@ -2554,7 +2572,7 @@ static void
__yy_memcpy (to, from, count)
char *to;
char *from;
- int count;
+ unsigned int count;
{
register char *f = from;
register char *t = to;
@@ -2569,10 +2587,10 @@ __yy_memcpy (to, from, count)
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
-__yy_memcpy (char *to, char *from, int count)
+__yy_memcpy (char *to, char *from, unsigned int count)
{
- register char *f = from;
register char *t = to;
+ register char *f = from;
register int i = count;
while (i-- > 0)
@@ -2582,7 +2600,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
-#line 196 "/usr/share/misc/bison.simple"
+#line 217 "/usr/lib/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -2603,6 +2621,15 @@ __yy_memcpy (char *to, char *from, int count)
#define YYPARSE_PARAM_DECL
#endif /* not YYPARSE_PARAM */
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+#ifdef YYPARSE_PARAM
+int yyparse (void *);
+#else
+int yyparse (void);
+#endif
+#endif
+
int
yyparse(YYPARSE_PARAM_ARG)
YYPARSE_PARAM_DECL
@@ -2631,6 +2658,7 @@ yyparse(YYPARSE_PARAM_ARG)
#endif
int yystacksize = YYINITDEPTH;
+ int yyfree_stacks = 0;
#ifdef YYPURE
int yychar;
@@ -2715,18 +2743,32 @@ yynewstate:
if (yystacksize >= YYMAXDEPTH)
{
yyerror("parser stack overflow");
+ if (yyfree_stacks)
+ {
+ free (yyss);
+ free (yyvs);
+#ifdef YYLSP_NEEDED
+ free (yyls);
+#endif
+ }
return 2;
}
yystacksize *= 2;
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
- yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
- __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
- yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
- __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
+#ifndef YYSTACK_USE_ALLOCA
+ yyfree_stacks = 1;
+#endif
+ yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss, (char *)yyss1,
+ size * (unsigned int) sizeof (*yyssp));
+ yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs, (char *)yyvs1,
+ size * (unsigned int) sizeof (*yyvsp));
#ifdef YYLSP_NEEDED
- yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
- __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
+ yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls, (char *)yyls1,
+ size * (unsigned int) sizeof (*yylsp));
#endif
#endif /* no yyoverflow */
@@ -4978,7 +5020,7 @@ case 503:
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/share/misc/bison.simple"
+#line 543 "/usr/lib/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -5173,6 +5215,30 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
+
+ yyacceptlab:
+ /* YYACCEPT comes here. */
+ if (yyfree_stacks)
+ {
+ free (yyss);
+ free (yyvs);
+#ifdef YYLSP_NEEDED
+ free (yyls);
+#endif
+ }
+ return 0;
+
+ yyabortlab:
+ /* YYABORT comes here. */
+ if (yyfree_stacks)
+ {
+ free (yyss);
+ free (yyvs);
+#ifdef YYLSP_NEEDED
+ free (yyls);
+#endif
+ }
+ return 1;
}
#line 2546 "./parse.y"
@@ -5564,7 +5630,7 @@ yyerror (msg)
else
java_error_count++;
- if (elc.col == 0 && msg[1] == ';')
+ if (elc.col == 0 && msg && msg[1] == ';')
{
elc.col = ctxp->p_line->char_col-1;
elc.line = ctxp->p_line->lineno;
@@ -6171,9 +6237,9 @@ maybe_make_nested_class_name (name)
if (CPC_INNER_P ())
{
make_nested_class_name (GET_CPC_LIST ());
- obstack_grow (&temporary_obstack,
- IDENTIFIER_POINTER (name),
- IDENTIFIER_LENGTH (name));
+ obstack_grow0 (&temporary_obstack,
+ IDENTIFIER_POINTER (name),
+ IDENTIFIER_LENGTH (name));
id = get_identifier (obstack_finish (&temporary_obstack));
if (ctxp->package)
QUALIFIED_P (id) = 1;
@@ -10871,6 +10937,12 @@ java_expand_classes ()
java_layout_classes ();
java_parse_abort_on_error ();
+ /* The list of packages declaration seen so far needs to be
+ reversed, so that package declared in a file being compiled gets
+ priority over packages declared as a side effect of parsing other
+ files.*/
+ package_list = nreverse (package_list);
+
saved_ctxp = ctxp_for_generation;
for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
{
@@ -13595,8 +13667,7 @@ java_complete_lhs (node)
nn = java_complete_tree (wfl_op1);
if (nn == error_mark_node)
return error_mark_node;
- if ((cn = patch_string (nn)))
- nn = cn;
+
TREE_OPERAND (node, 0) = nn;
}
if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
@@ -13604,8 +13675,7 @@ java_complete_lhs (node)
nn = java_complete_tree (wfl_op2);
if (nn == error_mark_node)
return error_mark_node;
- if ((cn = patch_string (nn)))
- nn = cn;
+
TREE_OPERAND (node, 1) = nn;
}
return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
@@ -14721,7 +14791,7 @@ patch_binop (node, wfl_op1, wfl_op2)
tree op2 = TREE_OPERAND (node, 1);
tree op1_type = TREE_TYPE (op1);
tree op2_type = TREE_TYPE (op2);
- tree prom_type = NULL_TREE;
+ tree prom_type = NULL_TREE, cn;
int code = TREE_CODE (node);
/* If 1, tell the routine that we have to return error_mark_node
@@ -14999,6 +15069,18 @@ patch_binop (node, wfl_op1, wfl_op2)
/* 15.20 Equality Operator */
case EQ_EXPR:
case NE_EXPR:
+ /* It's time for us to patch the strings. */
+ if ((cn = patch_string (op1)))
+ {
+ op1 = cn;
+ op1_type = TREE_TYPE (op1);
+ }
+ if ((cn = patch_string (op2)))
+ {
+ op2 = cn;
+ op2_type = TREE_TYPE (op2);
+ }
+
/* 15.20.1 Numerical Equality Operators == and != */
/* Binary numeric promotion is performed on the operands */
if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 17e74c2dd59..d427c341aaf 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -2932,7 +2932,7 @@ yyerror (msg)
else
java_error_count++;
- if (elc.col == 0 && msg[1] == ';')
+ if (elc.col == 0 && msg && msg[1] == ';')
{
elc.col = ctxp->p_line->char_col-1;
elc.line = ctxp->p_line->lineno;
@@ -3539,9 +3539,9 @@ maybe_make_nested_class_name (name)
if (CPC_INNER_P ())
{
make_nested_class_name (GET_CPC_LIST ());
- obstack_grow (&temporary_obstack,
- IDENTIFIER_POINTER (name),
- IDENTIFIER_LENGTH (name));
+ obstack_grow0 (&temporary_obstack,
+ IDENTIFIER_POINTER (name),
+ IDENTIFIER_LENGTH (name));
id = get_identifier (obstack_finish (&temporary_obstack));
if (ctxp->package)
QUALIFIED_P (id) = 1;
@@ -8239,6 +8239,12 @@ java_expand_classes ()
java_layout_classes ();
java_parse_abort_on_error ();
+ /* The list of packages declaration seen so far needs to be
+ reversed, so that package declared in a file being compiled gets
+ priority over packages declared as a side effect of parsing other
+ files.*/
+ package_list = nreverse (package_list);
+
saved_ctxp = ctxp_for_generation;
for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
{
@@ -10963,8 +10969,7 @@ java_complete_lhs (node)
nn = java_complete_tree (wfl_op1);
if (nn == error_mark_node)
return error_mark_node;
- if ((cn = patch_string (nn)))
- nn = cn;
+
TREE_OPERAND (node, 0) = nn;
}
if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
@@ -10972,8 +10977,7 @@ java_complete_lhs (node)
nn = java_complete_tree (wfl_op2);
if (nn == error_mark_node)
return error_mark_node;
- if ((cn = patch_string (nn)))
- nn = cn;
+
TREE_OPERAND (node, 1) = nn;
}
return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
@@ -12089,7 +12093,7 @@ patch_binop (node, wfl_op1, wfl_op2)
tree op2 = TREE_OPERAND (node, 1);
tree op1_type = TREE_TYPE (op1);
tree op2_type = TREE_TYPE (op2);
- tree prom_type = NULL_TREE;
+ tree prom_type = NULL_TREE, cn;
int code = TREE_CODE (node);
/* If 1, tell the routine that we have to return error_mark_node
@@ -12367,6 +12371,18 @@ patch_binop (node, wfl_op1, wfl_op2)
/* 15.20 Equality Operator */
case EQ_EXPR:
case NE_EXPR:
+ /* It's time for us to patch the strings. */
+ if ((cn = patch_string (op1)))
+ {
+ op1 = cn;
+ op1_type = TREE_TYPE (op1);
+ }
+ if ((cn = patch_string (op2)))
+ {
+ op2 = cn;
+ op2_type = TREE_TYPE (op2);
+ }
+
/* 15.20.1 Numerical Equality Operators == and != */
/* Binary numeric promotion is performed on the operands */
if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
diff --git a/gcc/loop.c b/gcc/loop.c
index cbb1731deae..7dd557da20a 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -308,6 +308,8 @@ static int replace_loop_reg PARAMS ((rtx *, void *));
static void note_reg_stored PARAMS ((rtx, rtx, void *));
static void try_copy_prop PARAMS ((const struct loop *, rtx, unsigned int));
static int replace_label PARAMS ((rtx *, void *));
+static rtx check_insn_for_givs PARAMS((struct loop *, rtx, int, int));
+static rtx check_insn_for_bivs PARAMS((struct loop *, rtx, int, int));
typedef struct rtx_and_int {
rtx r;
@@ -3694,127 +3696,47 @@ static rtx addr_placeholder;
was rerun in loop_optimize whenever a register was added or moved.
Also, some of the optimizations could be a little less conservative. */
-/* Perform strength reduction and induction variable elimination.
-
- Pseudo registers created during this function will be beyond the last
- valid index in several tables including n_times_set and regno_last_uid.
- This does not cause a problem here, because the added registers cannot be
- givs outside of their loop, and hence will never be reconsidered.
- But scan_loop must check regnos to make sure they are in bounds. */
-
-static void
-strength_reduce (loop, insn_count, unroll_p, bct_p)
+/* Scan the loop body and call FNCALL for each insn. In the addition to the
+ LOOP and INSN parameters pass MAYBE_MULTIPLE and NOT_EVERY_ITERATION to the
+ callback.
+
+ NOT_EVERY_ITERATION if current insn is not executed at least once for every
+ loop iteration except for the last one.
+
+ MAYBE_MULTIPLE is 1 if current insn may be executed more than once for every
+ loop iteration.
+ */
+void
+for_each_insn_in_loop (loop, fncall)
struct loop *loop;
- int insn_count;
- int unroll_p, bct_p ATTRIBUTE_UNUSED;
+ loop_insn_callback fncall;
{
- rtx p;
- rtx set;
- rtx inc_val;
- rtx mult_val;
- rtx dest_reg;
- rtx *location;
/* This is 1 if current insn is not executed at least once for every loop
iteration. */
int not_every_iteration = 0;
- /* This is 1 if current insn may be executed more than once for every
- loop iteration. */
int maybe_multiple = 0;
- /* This is 1 if we have past a branch back to the top of the loop
- (aka a loop latch). */
int past_loop_latch = 0;
- /* Temporary list pointers for traversing loop_iv_list. */
- struct iv_class *bl, **backbl;
- struct loop_info *loop_info = LOOP_INFO (loop);
- /* Ratio of extra register life span we can justify
- for saving an instruction. More if loop doesn't call subroutines
- since in that case saving an insn makes more difference
- and more registers are available. */
- /* ??? could set this to last value of threshold in move_movables */
- int threshold = (loop_info->has_call ? 1 : 2) * (3 + n_non_fixed_regs);
- /* Map of pseudo-register replacements. */
- rtx *reg_map = NULL;
- int reg_map_size;
- int call_seen;
- rtx test;
- rtx end_insert_before;
int loop_depth = 0;
- int n_extra_increment;
- int unrolled_insn_copies = 0;
- rtx loop_start = loop->start;
- rtx loop_end = loop->end;
- rtx loop_scan_start = loop->scan_start;
- rtx loop_top = loop->top;
- rtx loop_cont = loop->cont;
+ rtx p;
/* If loop_scan_start points to the loop exit test, we have to be wary of
subversive use of gotos inside expression statements. */
- if (prev_nonnote_insn (loop_scan_start) != prev_nonnote_insn (loop_start))
- maybe_multiple = back_branch_in_range_p (loop, loop_scan_start);
-
- VARRAY_INT_INIT (reg_iv_type, max_reg_before_loop, "reg_iv_type");
- VARRAY_GENERIC_PTR_INIT (reg_iv_info, max_reg_before_loop, "reg_iv_info");
- reg_biv_class = (struct iv_class **)
- xcalloc (max_reg_before_loop, sizeof (struct iv_class *));
-
- loop_iv_list = 0;
- addr_placeholder = gen_reg_rtx (Pmode);
-
- /* Save insn immediately after the loop_end. Insns inserted after loop_end
- must be put before this insn, so that they will appear in the right
- order (i.e. loop order).
-
- If loop_end is the end of the current function, then emit a
- NOTE_INSN_DELETED after loop_end and set end_insert_before to the
- dummy note insn. */
- if (NEXT_INSN (loop_end) != 0)
- end_insert_before = NEXT_INSN (loop_end);
- else
- end_insert_before = emit_note_after (NOTE_INSN_DELETED, loop_end);
+ if (prev_nonnote_insn (loop->scan_start) != prev_nonnote_insn (loop->start))
+ maybe_multiple = back_branch_in_range_p (loop, loop->scan_start);
/* Scan through loop to find all possible bivs. */
- for (p = next_insn_in_loop (loop, loop_scan_start);
+ for (p = next_insn_in_loop (loop, loop->scan_start);
p != NULL_RTX;
p = next_insn_in_loop (loop, p))
{
- if (GET_CODE (p) == INSN
- && (set = single_set (p))
- && GET_CODE (SET_DEST (set)) == REG)
- {
- dest_reg = SET_DEST (set);
- if (REGNO (dest_reg) < max_reg_before_loop
- && REGNO (dest_reg) >= FIRST_PSEUDO_REGISTER
- && REG_IV_TYPE (REGNO (dest_reg)) != NOT_BASIC_INDUCT)
- {
- int multi_insn_incr = 0;
-
- if (basic_induction_var (loop, SET_SRC (set),
- GET_MODE (SET_SRC (set)),
- dest_reg, p, &inc_val, &mult_val,
- &location, &multi_insn_incr))
- {
- /* It is a possible basic induction variable.
- Create and initialize an induction structure for it. */
-
- struct induction *v
- = (struct induction *) alloca (sizeof (struct induction));
-
- record_biv (v, p, dest_reg, inc_val, mult_val, location,
- not_every_iteration, maybe_multiple,
- multi_insn_incr);
- REG_IV_TYPE (REGNO (dest_reg)) = BASIC_INDUCT;
- }
- else if (REGNO (dest_reg) < max_reg_before_loop)
- REG_IV_TYPE (REGNO (dest_reg)) = NOT_BASIC_INDUCT;
- }
- }
+ p = fncall (loop, p, not_every_iteration, maybe_multiple);
/* Past CODE_LABEL, we get to insns that may be executed multiple
- times. The only way we can be sure that they can't is if every
- jump insn between here and the end of the loop either
- returns, exits the loop, is a jump to a location that is still
- behind the label, or is a jump to the loop start. */
+ times. The only way we can be sure that they can't is if every
+ jump insn between here and the end of the loop either
+ returns, exits the loop, is a jump to a location that is still
+ behind the label, or is a jump to the loop start. */
if (GET_CODE (p) == CODE_LABEL)
{
@@ -3825,24 +3747,24 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
while (1)
{
insn = NEXT_INSN (insn);
- if (insn == loop_scan_start)
+ if (insn == loop->scan_start)
break;
- if (insn == loop_end)
+ if (insn == loop->end)
{
- if (loop_top != 0)
- insn = loop_top;
+ if (loop->top != 0)
+ insn = loop->top;
else
break;
- if (insn == loop_scan_start)
+ if (insn == loop->scan_start)
break;
}
if (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) != RETURN
- && (! condjump_p (insn)
+ && (!condjump_p (insn)
|| (JUMP_LABEL (insn) != 0
- && JUMP_LABEL (insn) != loop_scan_start
- && ! loop_insn_first_p (p, JUMP_LABEL (insn)))))
+ && JUMP_LABEL (insn) != loop->scan_start
+ && !loop_insn_first_p (p, JUMP_LABEL (insn)))))
{
maybe_multiple = 1;
break;
@@ -3851,29 +3773,29 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
}
/* Past a jump, we get to insns for which we can't count
- on whether they will be executed during each iteration. */
+ on whether they will be executed during each iteration. */
/* This code appears twice in strength_reduce. There is also similar
- code in scan_loop. */
+ code in scan_loop. */
if (GET_CODE (p) == JUMP_INSN
- /* If we enter the loop in the middle, and scan around to the
- beginning, don't set not_every_iteration for that.
- This can be any kind of jump, since we want to know if insns
- will be executed if the loop is executed. */
- && ! (JUMP_LABEL (p) == loop_top
- && ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
- || (NEXT_INSN (p) == loop_end && condjump_p (p)))))
+ /* If we enter the loop in the middle, and scan around to the
+ beginning, don't set not_every_iteration for that.
+ This can be any kind of jump, since we want to know if insns
+ will be executed if the loop is executed. */
+ && !(JUMP_LABEL (p) == loop->top
+ && ((NEXT_INSN (NEXT_INSN (p)) == loop->end && simplejump_p (p))
+ || (NEXT_INSN (p) == loop->end && condjump_p (p)))))
{
rtx label = 0;
/* If this is a jump outside the loop, then it also doesn't
matter. Check to see if the target of this branch is on the
loop->exits_labels list. */
-
+
for (label = loop->exit_labels; label; label = LABEL_NEXTREF (label))
if (XEXP (label, 0) == JUMP_LABEL (p))
break;
- if (! label)
+ if (!label)
not_every_iteration = 1;
}
@@ -3896,34 +3818,93 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
}
/* Note if we pass a loop latch. If we do, then we can not clear
- NOT_EVERY_ITERATION below when we pass the last CODE_LABEL in
- a loop since a jump before the last CODE_LABEL may have started
- a new loop iteration.
-
- Note that LOOP_TOP is only set for rotated loops and we need
- this check for all loops, so compare against the CODE_LABEL
- which immediately follows LOOP_START. */
- if (GET_CODE (p) == JUMP_INSN
- && JUMP_LABEL (p) == NEXT_INSN (loop_start))
+ NOT_EVERY_ITERATION below when we pass the last CODE_LABEL in
+ a loop since a jump before the last CODE_LABEL may have started
+ a new loop iteration.
+
+ Note that LOOP_TOP is only set for rotated loops and we need
+ this check for all loops, so compare against the CODE_LABEL
+ which immediately follows LOOP_START. */
+ if (GET_CODE (p) == JUMP_INSN
+ && JUMP_LABEL (p) == NEXT_INSN (loop->start))
past_loop_latch = 1;
/* Unlike in the code motion pass where MAYBE_NEVER indicates that
- an insn may never be executed, NOT_EVERY_ITERATION indicates whether
- or not an insn is known to be executed each iteration of the
- loop, whether or not any iterations are known to occur.
+ an insn may never be executed, NOT_EVERY_ITERATION indicates whether
+ or not an insn is known to be executed each iteration of the
+ loop, whether or not any iterations are known to occur.
- Therefore, if we have just passed a label and have no more labels
- between here and the test insn of the loop, and we have not passed
- a jump to the top of the loop, then we know these insns will be
- executed each iteration. */
+ Therefore, if we have just passed a label and have no more labels
+ between here and the test insn of the loop, and we have not passed
+ a jump to the top of the loop, then we know these insns will be
+ executed each iteration. */
- if (not_every_iteration
- && ! past_loop_latch
+ if (not_every_iteration
+ && !past_loop_latch
&& GET_CODE (p) == CODE_LABEL
- && no_labels_between_p (p, loop_end)
- && loop_insn_first_p (p, loop_cont))
+ && no_labels_between_p (p, loop->end)
+ && loop_insn_first_p (p, loop->cont))
not_every_iteration = 0;
}
+}
+
+/* Perform strength reduction and induction variable elimination.
+
+ Pseudo registers created during this function will be beyond the last
+ valid index in several tables including n_times_set and regno_last_uid.
+ This does not cause a problem here, because the added registers cannot be
+ givs outside of their loop, and hence will never be reconsidered.
+ But scan_loop must check regnos to make sure they are in bounds. */
+
+static void
+strength_reduce (loop, insn_count, unroll_p, bct_p)
+ struct loop *loop;
+ int insn_count;
+ int unroll_p, bct_p ATTRIBUTE_UNUSED;
+{
+ rtx p;
+ /* Temporary list pointers for traversing loop_iv_list. */
+ struct iv_class *bl, **backbl;
+ struct loop_info *loop_info = LOOP_INFO (loop);
+ /* Ratio of extra register life span we can justify
+ for saving an instruction. More if loop doesn't call subroutines
+ since in that case saving an insn makes more difference
+ and more registers are available. */
+ /* ??? could set this to last value of threshold in move_movables */
+ int threshold = (loop_info->has_call ? 1 : 2) * (3 + n_non_fixed_regs);
+ /* Map of pseudo-register replacements. */
+ rtx *reg_map = NULL;
+ int reg_map_size;
+ int call_seen;
+ rtx test;
+ rtx end_insert_before;
+ int n_extra_increment;
+ int unrolled_insn_copies = 0;
+ rtx loop_start = loop->start;
+ rtx loop_end = loop->end;
+ rtx loop_scan_start = loop->scan_start;
+
+ VARRAY_INT_INIT (reg_iv_type, max_reg_before_loop, "reg_iv_type");
+ VARRAY_GENERIC_PTR_INIT (reg_iv_info, max_reg_before_loop, "reg_iv_info");
+ reg_biv_class = (struct iv_class **)
+ xcalloc (max_reg_before_loop, sizeof (struct iv_class *));
+
+ loop_iv_list = 0;
+ addr_placeholder = gen_reg_rtx (Pmode);
+
+ /* Save insn immediately after the loop_end. Insns inserted after loop_end
+ must be put before this insn, so that they will appear in the right
+ order (i.e. loop order).
+
+ If loop_end is the end of the current function, then emit a
+ NOTE_INSN_DELETED after loop_end and set end_insert_before to the
+ dummy note insn. */
+ if (NEXT_INSN (loop_end) != 0)
+ end_insert_before = NEXT_INSN (loop_end);
+ else
+ end_insert_before = emit_note_after (NOTE_INSN_DELETED, loop_end);
+
+ for_each_insn_in_loop (loop, check_insn_for_bivs);
/* Scan loop_iv_list to remove all regs that proved not to be bivs.
Make a sanity check against n_times_set. */
@@ -4430,203 +4411,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
/* Search the loop for general induction variables. */
- /* A register is a giv if: it is only set once, it is a function of a
- biv and a constant (or invariant), and it is not a biv. */
-
- not_every_iteration = 0;
- loop_depth = 0;
- maybe_multiple = 0;
- p = loop_scan_start;
- while (1)
- {
- p = NEXT_INSN (p);
- /* At end of a straight-in loop, we are done.
- At end of a loop entered at the bottom, scan the top. */
- if (p == loop_scan_start)
- break;
- if (p == loop_end)
- {
- if (loop_top != 0)
- p = loop_top;
- else
- break;
- if (p == loop_scan_start)
- break;
- }
-
- /* Look for a general induction variable in a register. */
- if (GET_CODE (p) == INSN
- && (set = single_set (p))
- && GET_CODE (SET_DEST (set)) == REG
- && ! VARRAY_CHAR (may_not_optimize, REGNO (SET_DEST (set))))
- {
- rtx src_reg;
- rtx add_val;
- rtx mult_val;
- int benefit;
- rtx regnote = 0;
- rtx last_consec_insn;
-
- dest_reg = SET_DEST (set);
- if (REGNO (dest_reg) < FIRST_PSEUDO_REGISTER)
- continue;
-
- if (/* SET_SRC is a giv. */
- (general_induction_var (loop, SET_SRC (set), &src_reg, &add_val,
- &mult_val, 0, &benefit)
- /* Equivalent expression is a giv. */
- || ((regnote = find_reg_note (p, REG_EQUAL, NULL_RTX))
- && general_induction_var (loop, XEXP (regnote, 0), &src_reg,
- &add_val, &mult_val, 0,
- &benefit)))
- /* Don't try to handle any regs made by loop optimization.
- We have nothing on them in regno_first_uid, etc. */
- && REGNO (dest_reg) < max_reg_before_loop
- /* Don't recognize a BASIC_INDUCT_VAR here. */
- && dest_reg != src_reg
- /* This must be the only place where the register is set. */
- && (VARRAY_INT (n_times_set, REGNO (dest_reg)) == 1
- /* or all sets must be consecutive and make a giv. */
- || (benefit = consec_sets_giv (loop, benefit, p,
- src_reg, dest_reg,
- &add_val, &mult_val,
- &last_consec_insn))))
- {
- struct induction *v
- = (struct induction *) alloca (sizeof (struct induction));
-
- /* If this is a library call, increase benefit. */
- if (find_reg_note (p, REG_RETVAL, NULL_RTX))
- benefit += libcall_benefit (p);
-
- /* Skip the consecutive insns, if there are any. */
- if (VARRAY_INT (n_times_set, REGNO (dest_reg)) != 1)
- p = last_consec_insn;
-
- record_giv (loop, v, p, src_reg, dest_reg, mult_val, add_val,
- benefit, DEST_REG, not_every_iteration,
- maybe_multiple, NULL_PTR);
-
- }
- }
-
-#ifndef DONT_REDUCE_ADDR
- /* Look for givs which are memory addresses. */
- /* This resulted in worse code on a VAX 8600. I wonder if it
- still does. */
- if (GET_CODE (p) == INSN)
- find_mem_givs (loop, PATTERN (p), p, not_every_iteration,
- maybe_multiple);
-#endif
-
- /* Update the status of whether giv can derive other givs. This can
- change when we pass a label or an insn that updates a biv. */
- if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
- || GET_CODE (p) == CODE_LABEL)
- update_giv_derive (loop, p);
-
- /* Past CODE_LABEL, we get to insns that may be executed multiple
- times. The only way we can be sure that they can't is if every
- every jump insn between here and the end of the loop either
- returns, exits the loop, is a forward jump, or is a jump
- to the loop start. */
-
- if (GET_CODE (p) == CODE_LABEL)
- {
- rtx insn = p;
-
- maybe_multiple = 0;
-
- while (1)
- {
- insn = NEXT_INSN (insn);
- if (insn == loop_scan_start)
- break;
- if (insn == loop_end)
- {
- if (loop_top != 0)
- insn = loop_top;
- else
- break;
- if (insn == loop_scan_start)
- break;
- }
-
- if (GET_CODE (insn) == JUMP_INSN
- && GET_CODE (PATTERN (insn)) != RETURN
- && (! condjump_p (insn)
- || (JUMP_LABEL (insn) != 0
- && JUMP_LABEL (insn) != loop_scan_start
- && (INSN_UID (JUMP_LABEL (insn)) >= max_uid_for_loop
- || INSN_UID (insn) >= max_uid_for_loop
- || (INSN_LUID (JUMP_LABEL (insn))
- < INSN_LUID (insn))))))
- {
- maybe_multiple = 1;
- break;
- }
- }
- }
-
- /* Past a jump, we get to insns for which we can't count
- on whether they will be executed during each iteration. */
- /* This code appears twice in strength_reduce. There is also similar
- code in scan_loop. */
- if (GET_CODE (p) == JUMP_INSN
- /* If we enter the loop in the middle, and scan around to the
- beginning, don't set not_every_iteration for that.
- This can be any kind of jump, since we want to know if insns
- will be executed if the loop is executed. */
- && ! (JUMP_LABEL (p) == loop_top
- && ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
- || (NEXT_INSN (p) == loop_end && condjump_p (p)))))
- {
- rtx label = 0;
-
- /* If this is a jump outside the loop, then it also doesn't
- matter. Check to see if the target of this branch is on the
- loop->exits_labels list. */
-
- for (label = loop->exit_labels; label; label = LABEL_NEXTREF (label))
- if (XEXP (label, 0) == JUMP_LABEL (p))
- break;
-
- if (! label)
- not_every_iteration = 1;
- }
-
- else if (GET_CODE (p) == NOTE)
- {
- /* At the virtual top of a converted loop, insns are again known to
- be executed each iteration: logically, the loop begins here
- even though the exit code has been duplicated.
-
- Insns are also again known to be executed each iteration at
- the LOOP_CONT note. */
- if ((NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_VTOP
- || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_CONT)
- && loop_depth == 0)
- not_every_iteration = 0;
- else if (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG)
- loop_depth++;
- else if (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)
- loop_depth--;
- }
-
- /* Unlike in the code motion pass where MAYBE_NEVER indicates that
- an insn may never be executed, NOT_EVERY_ITERATION indicates whether
- or not an insn is known to be executed each iteration of the
- loop, whether or not any iterations are known to occur.
-
- Therefore, if we have just passed a label and have no more labels
- between here and the test insn of the loop, we know these insns
- will be executed each iteration. */
-
- if (not_every_iteration && GET_CODE (p) == CODE_LABEL
- && no_labels_between_p (p, loop_end)
- && loop_insn_first_p (p, loop_cont))
- not_every_iteration = 0;
- }
+ for_each_insn_in_loop (loop, check_insn_for_givs);
/* Try to calculate and save the number of loop iterations. This is
set to zero if the actual number can not be calculated. This must
@@ -5282,6 +5067,139 @@ egress:
free (reg_map);
}
+/*Record all basic induction variables calculated in the insn. */
+static rtx
+check_insn_for_bivs (loop, p, not_every_iteration, maybe_multiple)
+ struct loop *loop;
+ rtx p;
+ int not_every_iteration;
+ int maybe_multiple;
+{
+ rtx set;
+ rtx dest_reg;
+ rtx inc_val;
+ rtx mult_val;
+ rtx *location;
+
+ if (GET_CODE (p) == INSN
+ && (set = single_set (p))
+ && GET_CODE (SET_DEST (set)) == REG)
+ {
+ dest_reg = SET_DEST (set);
+ if (REGNO (dest_reg) < max_reg_before_loop
+ && REGNO (dest_reg) >= FIRST_PSEUDO_REGISTER
+ && REG_IV_TYPE (REGNO (dest_reg)) != NOT_BASIC_INDUCT)
+ {
+ int multi_insn_incr = 0;
+
+ if (basic_induction_var (loop, SET_SRC (set),
+ GET_MODE (SET_SRC (set)),
+ dest_reg, p, &inc_val, &mult_val,
+ &location, &multi_insn_incr))
+ {
+ /* It is a possible basic induction variable.
+ Create and initialize an induction structure for it. */
+
+ struct induction *v
+ = (struct induction *) oballoc (sizeof (struct induction));
+
+ record_biv (v, p, dest_reg, inc_val, mult_val, location,
+ not_every_iteration, maybe_multiple,
+ multi_insn_incr);
+ REG_IV_TYPE (REGNO (dest_reg)) = BASIC_INDUCT;
+ }
+ else if (REGNO (dest_reg) < max_reg_before_loop)
+ REG_IV_TYPE (REGNO (dest_reg)) = NOT_BASIC_INDUCT;
+ }
+ }
+ return p;
+}
+
+/* Record all givs calculated in the insn.
+ A register is a giv if: it is only set once, it is a function of a
+ biv and a constant (or invariant), and it is not a biv. */
+static rtx
+check_insn_for_givs (loop, p, not_every_iteration, maybe_multiple)
+ struct loop *loop;
+ rtx p;
+ int not_every_iteration;
+ int maybe_multiple;
+{
+ rtx set;
+ /* Look for a general induction variable in a register. */
+ if (GET_CODE (p) == INSN
+ && (set = single_set (p))
+ && GET_CODE (SET_DEST (set)) == REG
+ && ! VARRAY_CHAR (may_not_optimize, REGNO (SET_DEST (set))))
+ {
+ rtx src_reg;
+ rtx dest_reg;
+ rtx add_val;
+ rtx mult_val;
+ int benefit;
+ rtx regnote = 0;
+ rtx last_consec_insn;
+
+ dest_reg = SET_DEST (set);
+ if (REGNO (dest_reg) < FIRST_PSEUDO_REGISTER)
+ return p;
+
+ if (/* SET_SRC is a giv. */
+ (general_induction_var (loop, SET_SRC (set), &src_reg, &add_val,
+ &mult_val, 0, &benefit)
+ /* Equivalent expression is a giv. */
+ || ((regnote = find_reg_note (p, REG_EQUAL, NULL_RTX))
+ && general_induction_var (loop, XEXP (regnote, 0), &src_reg,
+ &add_val, &mult_val, 0,
+ &benefit)))
+ /* Don't try to handle any regs made by loop optimization.
+ We have nothing on them in regno_first_uid, etc. */
+ && REGNO (dest_reg) < max_reg_before_loop
+ /* Don't recognize a BASIC_INDUCT_VAR here. */
+ && dest_reg != src_reg
+ /* This must be the only place where the register is set. */
+ && (VARRAY_INT (n_times_set, REGNO (dest_reg)) == 1
+ /* or all sets must be consecutive and make a giv. */
+ || (benefit = consec_sets_giv (loop, benefit, p,
+ src_reg, dest_reg,
+ &add_val, &mult_val,
+ &last_consec_insn))))
+ {
+ struct induction *v
+ = (struct induction *) oballoc (sizeof (struct induction));
+
+ /* If this is a library call, increase benefit. */
+ if (find_reg_note (p, REG_RETVAL, NULL_RTX))
+ benefit += libcall_benefit (p);
+
+ /* Skip the consecutive insns, if there are any. */
+ if (VARRAY_INT (n_times_set, REGNO (dest_reg)) != 1)
+ p = last_consec_insn;
+
+ record_giv (loop, v, p, src_reg, dest_reg, mult_val, add_val,
+ benefit, DEST_REG, not_every_iteration,
+ maybe_multiple, NULL_PTR);
+
+ }
+ }
+
+#ifndef DONT_REDUCE_ADDR
+ /* Look for givs which are memory addresses. */
+ /* This resulted in worse code on a VAX 8600. I wonder if it
+ still does. */
+ if (GET_CODE (p) == INSN)
+ find_mem_givs (loop, PATTERN (p), p, not_every_iteration,
+ maybe_multiple);
+#endif
+
+ /* Update the status of whether giv can derive other givs. This can
+ change when we pass a label or an insn that updates a biv. */
+ if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
+ || GET_CODE (p) == CODE_LABEL)
+ update_giv_derive (loop, p);
+ return p;
+}
+
/* Return 1 if X is a valid source for an initial value (or as value being
compared against in an initial test).
@@ -7722,11 +7640,24 @@ emit_iv_add_mult (b, m, a, reg, insert_before)
{
rtx seq;
rtx result;
+ rtx last;
+ rtx set;
+ rtx exp;
+ enum machine_mode mode = GET_MODE (reg);
/* Prevent unexpected sharing of these rtx. */
a = copy_rtx (a);
b = copy_rtx (b);
+ /* We may be faced to (plus (symbol_ref) (const_int)). We want to simplify
+ this to CONST rtx. */
+ exp = simplify_rtx (a);
+ if (exp)
+ a = exp;
+ exp = simplify_rtx (b);
+ if (exp)
+ b = exp;
+
/* Increase the lifetime of any invariants moved further in code. */
update_reg_last_use (a, insert_before);
update_reg_last_use (b, insert_before);
@@ -7739,7 +7670,7 @@ emit_iv_add_mult (b, m, a, reg, insert_before)
seq = gen_sequence ();
end_sequence ();
- emit_insn_before (seq, insert_before);
+ last = emit_insn_before (seq, insert_before);
/* It is entirely possible that the expansion created lots of new
registers. Iterate over the sequence we just created and
@@ -7750,14 +7681,47 @@ emit_iv_add_mult (b, m, a, reg, insert_before)
int i;
for (i = 0; i < XVECLEN (seq, 0); ++i)
{
- rtx set = single_set (XVECEXP (seq, 0, i));
+ set = single_set (XVECEXP (seq, 0, i));
if (set && GET_CODE (SET_DEST (set)) == REG)
record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
}
+ last = XVECEXP (seq, 0, i - 1);
}
- else if (GET_CODE (seq) == SET
- && GET_CODE (SET_DEST (seq)) == REG)
- record_base_value (REGNO (SET_DEST (seq)), SET_SRC (seq), 0);
+ else
+ {
+ set = single_set (last);
+ if (set && GET_CODE (SET_DEST (set)) == REG)
+ record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
+ }
+ if (!last)
+ return;
+ /* Sequence really ought to end by set storing final value to the register.
+
+ Attach note indicating expression we've just calculated to it. This is
+ important for second run of loop optimizer to understand strength reduced
+ givs from the first run. */
+ if (GET_CODE (last) != INSN)
+ abort();
+ set = single_set (last);
+ if (!set)
+ return;
+ if (SET_DEST (set) != reg)
+ abort();
+
+ /* In case we start to emit some usefull notes to these insns, get abort
+ here, since we need to decide what information is more important. */
+ if (find_reg_note (last, REG_EQUIV, NULL_RTX)
+ || find_reg_note (last, REG_EQUAL, NULL_RTX))
+ abort();
+
+ /* Expression we've just caluclated. */
+ exp = simplify_gen_binary (PLUS, mode,
+ simplify_gen_binary (MULT, mode, b, m),
+ a);
+ REG_NOTES (last)
+ = gen_rtx_EXPR_LIST (REG_EQUAL,
+ exp,
+ REG_NOTES (last));
}
/* Test whether A * B can be computed without
@@ -9013,14 +8977,19 @@ update_reg_last_use (x, insn)
If EARLIEST is non-zero, it is a pointer to a place where the earliest
insn used in locating the condition was found. If a replacement test
of the condition is desired, it should be placed in front of that
- insn and we will be sure that the inputs are still valid. */
+ insn and we will be sure that the inputs are still valid.
+
+ If WANT_REG is non-zero, we wish the condition to be relative to that
+ register, if possible. Therefore, do not canonicalize the condition
+ further. */
rtx
-canonicalize_condition (insn, cond, reverse, earliest)
+canonicalize_condition (insn, cond, reverse, earliest, want_reg)
rtx insn;
rtx cond;
int reverse;
rtx *earliest;
+ rtx want_reg;
{
enum rtx_code code;
rtx prev = insn;
@@ -9050,7 +9019,9 @@ canonicalize_condition (insn, cond, reverse, earliest)
the same tests as a function of STORE_FLAG_VALUE as find_comparison_args
in cse.c */
- while (GET_RTX_CLASS (code) == '<' && op1 == CONST0_RTX (GET_MODE (op0)))
+ while (GET_RTX_CLASS (code) == '<'
+ && op1 == CONST0_RTX (GET_MODE (op0))
+ && op0 != want_reg)
{
/* Set non-zero when we find something of interest. */
rtx x = 0;
@@ -9291,7 +9262,7 @@ get_condition (jump, earliest)
= GET_CODE (XEXP (SET_SRC (PATTERN (jump)), 2)) == LABEL_REF
&& XEXP (XEXP (SET_SRC (PATTERN (jump)), 2), 0) == JUMP_LABEL (jump);
- return canonicalize_condition (jump, cond, reverse, earliest);
+ return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
}
/* Similar to above routine, except that we also put an invariant last
diff --git a/gcc/loop.h b/gcc/loop.h
index 703073372b6..9c4affb8442 100644
--- a/gcc/loop.h
+++ b/gcc/loop.h
@@ -247,4 +247,6 @@ void emit_unrolled_add PARAMS ((rtx, rtx, rtx));
int back_branch_in_range_p PARAMS ((const struct loop *, rtx));
int loop_insn_first_p PARAMS ((rtx, rtx));
+typedef rtx (*loop_insn_callback ) PARAMS ((struct loop *, rtx, int, int));
+void for_each_insn_in_loop PARAMS ((struct loop *, loop_insn_callback));
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 5f2a76ad9b9..304eb7400d2 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -3098,6 +3098,7 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
to be used for operand OPNUM of the insn, is converted from mode MODE to
WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
that it is accepted by the operand predicate. Return the new value. */
+
rtx
prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
int icode;
diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog
index 68ec053c3ed..f0e3041bbbe 100644
--- a/gcc/po/ChangeLog
+++ b/gcc/po/ChangeLog
@@ -1,3 +1,8 @@
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * POTFILES.in: Remove cccp.c and cexp.c. Comment out
+ alpha/vms-tramp.asm.
+
2000-04-05 Geoff Keating <geoffk@cygnus.com>
* POTFILES.in: Remove config/rs6000/eabi-ctors.c, which was
diff --git a/gcc/po/POTFILES.in b/gcc/po/POTFILES.in
index 1e4e63b5f87..994e94d867f 100644
--- a/gcc/po/POTFILES.in
+++ b/gcc/po/POTFILES.in
@@ -68,8 +68,6 @@ c-tree.h
c-typeck.c
caller-save.c
calls.c
-cccp.c
-cexp.c
../libiberty/choose-temp.c
collect2.c
combine.c
@@ -94,7 +92,7 @@ config/alpha/openbsd.h
config/alpha/osf.h
config/alpha/osf12.h
config/alpha/osf2or3.h
-config/alpha/vms-tramp.asm
+#config/alpha/vms-tramp.asm is part of the GCC library
config/alpha/vms.h
config/alpha/vxworks.h
config/alpha/win-nt.h
diff --git a/gcc/predict.c b/gcc/predict.c
index 2cae39a5798..958dbf925b8 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -180,4 +180,70 @@ estimate_probability (loops_info)
REG_NOTES (last_insn));
}
}
+
+/* __builtin_expect dropped tokens into the insn stream describing
+ expected values of registers. Generate branch probabilities
+ based off these values. */
+static rtx find_expected_value PARAMS ((rtx, rtx));
+
+void
+expected_value_to_br_prob ()
+{
+ rtx insn, cond, ev = NULL_RTX, ev_reg;
+
+ for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
+ {
+ switch (GET_CODE (insn))
+ {
+ case NOTE:
+ /* Look for expected value notes. */
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EXPECTED_VALUE)
+ {
+ ev = NOTE_EXPECTED_VALUE (insn);
+ ev_reg = XEXP (ev, 0);
+ }
+ continue;
+
+ case CODE_LABEL:
+ /* Never propagate across labels. */
+ ev = NULL_RTX;
+ continue;
+
+ default:
+ /* Look for insns that clobber the EV register. */
+ if (ev && reg_set_p (ev_reg, insn))
+ ev = NULL_RTX;
+ continue;
+
+ case JUMP_INSN:
+ /* Look for simple conditional branches. If we havn't got an
+ expected value yet, no point going further. */
+ if (GET_CODE (insn) != JUMP_INSN || ev == NULL_RTX)
+ continue;
+ if (! condjump_p (insn) || simplejump_p (insn))
+ continue;
+ break;
+ }
+
+ /* Collect the branch condition, hopefully relative to EV_REG. */
+ cond = XEXP (SET_SRC (PATTERN (insn)), 0);
+ cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg);
+ if (! cond || XEXP (cond, 0) != ev_reg)
+ continue;
+
+ /* Substitute and simplify. Given that the expression we're
+ building involves two constants, we should wind up with either
+ true or false. */
+ cond = gen_rtx_fmt_ee (GET_CODE (cond), VOIDmode,
+ XEXP (ev, 1), XEXP (cond, 1));
+ cond = simplify_rtx (cond);
+
+ /* Turn the condition into a scaled branch probability. */
+ if (cond == const1_rtx)
+ cond = GEN_INT (REG_BR_PROB_BASE);
+ else if (cond != const0_rtx)
+ abort ();
+ REG_NOTES (insn) = alloc_EXPR_LIST (REG_BR_PROB, cond, REG_NOTES (insn));
+ }
+}
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index ee7e64cebb5..8b7bebeb6f6 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -162,18 +162,19 @@ print_rtx (in_rtx)
case '0':
if (i == 3 && GET_CODE (in_rtx) == NOTE)
{
- if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_BEG
- || NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_END)
+ switch (NOTE_LINE_NUMBER (in_rtx))
{
+ case NOTE_INSN_EH_REGION_BEG:
+ case NOTE_INSN_EH_REGION_END:
if (flag_dump_unnumbered)
fprintf (outfile, " #");
else
fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx));
sawclose = 1;
- }
- else if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BLOCK_BEG
- || NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BLOCK_END)
- {
+ break;
+
+ case NOTE_INSN_BLOCK_BEG:
+ case NOTE_INSN_BLOCK_END:
fprintf (outfile, " ");
if (flag_dump_unnumbered)
fprintf (outfile, "#");
@@ -181,36 +182,51 @@ print_rtx (in_rtx)
fprintf (outfile, HOST_PTR_PRINTF,
(char *) NOTE_BLOCK (in_rtx));
sawclose = 1;
- }
- else if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_RANGE_START
- || NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_RANGE_END
- || NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_LIVE)
- {
+ break;
+
+ case NOTE_INSN_RANGE_START:
+ case NOTE_INSN_RANGE_END:
+ case NOTE_INSN_LIVE:
indent += 2;
if (!sawclose)
fprintf (outfile, " ");
print_rtx (NOTE_RANGE_INFO (in_rtx));
indent -= 2;
- }
- else if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_BASIC_BLOCK)
- {
- basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
+ break;
- if (bb != 0)
- fprintf (outfile, " [bb %d]", bb->index);
- }
- else
- {
- const char * const str = X0STR (in_rtx, i);
- if (str == 0)
- fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
- else
- {
- if (dump_for_graph)
- fprintf (outfile, " (\\\"%s\\\")", str);
- else
- fprintf (outfile, " (\"%s\")", str);
- }
+ case NOTE_INSN_BASIC_BLOCK:
+ {
+ basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
+ if (bb != 0)
+ fprintf (outfile, " [bb %d]", bb->index);
+ break;
+ }
+
+ case NOTE_INSN_EXPECTED_VALUE:
+ indent += 2;
+ if (!sawclose)
+ fprintf (outfile, " ");
+ print_rtx (NOTE_EXPECTED_VALUE (in_rtx));
+ indent -= 2;
+ break;
+
+ default:
+ {
+ const char * const str = X0STR (in_rtx, i);
+
+ if (NOTE_LINE_NUMBER (in_rtx) < 0)
+ ;
+ else if (str == 0)
+ fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
+ else
+ {
+ if (dump_for_graph)
+ fprintf (outfile, " (\\\"%s\\\")", str);
+ else
+ fprintf (outfile, " (\"%s\")", str);
+ }
+ break;
+ }
}
}
break;
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 6439423c89c..7ccf67e7d89 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -409,7 +409,11 @@ print_node (file, prefix, node, indent)
indent_to (file, indent + 3);
if (TREE_CODE (node) != FUNCTION_DECL)
- fprintf (file, " align %d", DECL_ALIGN (node));
+ {
+ fprintf (file, " align %d", DECL_ALIGN (node));
+ if (TREE_CODE (node) == FIELD_DECL)
+ fprintf (file, " offset_align %d", DECL_OFFSET_ALIGN (node));
+ }
else if (DECL_INLINE (node))
{
fprintf (file, " frame_size ");
diff --git a/gcc/protoize.c b/gcc/protoize.c
index 37e7ff83a75..7a58df23ef7 100644
--- a/gcc/protoize.c
+++ b/gcc/protoize.c
@@ -192,7 +192,7 @@ static const unexpansion unexpansions[] = {
static const int hash_mask = (HASH_TABLE_SIZE - 1);
/* Make a table of default system include directories
- just as it is done in cccp.c. */
+ just as it is done in cpp. */
#ifndef STANDARD_INCLUDE_DIR
#define STANDARD_INCLUDE_DIR "/usr/include"
diff --git a/gcc/real.c b/gcc/real.c
index 6acd2bf376a..2022aacbeb9 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -337,6 +337,13 @@ do { \
/* The exponent of 1.0 */
#define EXONE (0x3fff)
+#if defined(HOST_EBCDIC)
+/* bit 8 is significant in EBCDIC */
+#define CHARMASK 0xff
+#else
+#define CHARMASK 0x7f
+#endif
+
extern int extra_warnings;
extern unsigned EMUSHORT ezero[], ehalf[], eone[], etwo[];
extern unsigned EMUSHORT elog2[], esqrt2[];
@@ -4981,7 +4988,7 @@ etoasc (x, string, ndigs)
/* Round up and propagate carry-outs */
roun:
--s;
- k = *s & 0x7f;
+ k = *s & CHARMASK;
/* Carry out to most significant digit? */
if (k == '.')
{
@@ -5142,7 +5149,7 @@ asctoeg (ss, y, oprec)
nxtcom:
if (*s >= '0' && *s <= '9')
k = *s - '0';
- else if (*s >= 'a')
+ else if (*s >= 'a' && *s <= 'f')
k = 10 + *s - 'a';
else
k = 10 + *s - 'A';
@@ -5160,7 +5167,7 @@ asctoeg (ss, y, oprec)
|| (*sp >= 'A' && *sp <= 'F'))))
++sp;
/* Check for syntax error */
- c = *sp & 0x7f;
+ c = *sp & CHARMASK;
if ((base != 10 || ((c != 'e') && (c != 'E')))
&& (base != 16 || ((c != 'p') && (c != 'P')))
&& (c != '\0')
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 379def73cbb..cce40c0d7cf 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -900,30 +900,29 @@ mostly_true_jump (jump_insn, condition)
rtx jump_insn, condition;
{
rtx target_label = JUMP_LABEL (jump_insn);
- rtx insn;
+ rtx insn, note;
int rare_dest = rare_destination (target_label);
int rare_fallthrough = rare_destination (NEXT_INSN (jump_insn));
/* If branch probabilities are available, then use that number since it
always gives a correct answer. */
- if (flag_branch_probabilities)
+ note = find_reg_note (jump_insn, REG_BR_PROB, 0);
+ if (note)
{
- rtx note = find_reg_note (jump_insn, REG_BR_PROB, 0);
- if (note)
- {
- int prob = XINT (note, 0);
+ int prob = INTVAL (XEXP (note, 0));
- if (prob >= REG_BR_PROB_BASE * 9 / 10)
- return 2;
- else if (prob >= REG_BR_PROB_BASE / 2)
- return 1;
- else if (prob >= REG_BR_PROB_BASE / 10)
- return 0;
- else
- return -1;
- }
+ if (prob >= REG_BR_PROB_BASE * 9 / 10)
+ return 2;
+ else if (prob >= REG_BR_PROB_BASE / 2)
+ return 1;
+ else if (prob >= REG_BR_PROB_BASE / 10)
+ return 0;
+ else
+ return -1;
}
+ /* ??? Ought to use estimate_probability instead. */
+
/* If this is a branch outside a loop, it is highly unlikely. */
if (GET_CODE (PATTERN (jump_insn)) == SET
&& GET_CODE (SET_SRC (PATTERN (jump_insn))) == IF_THEN_ELSE
diff --git a/gcc/rtl.c b/gcc/rtl.c
index bfe3806c06d..80929e5032e 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -235,19 +235,19 @@ const char rtx_class[] = {
/* Names for kinds of NOTEs and REG_NOTEs. */
-const char * const note_insn_name[] =
+const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS] =
{
- 0, "NOTE_INSN_DELETED",
+ "", "NOTE_INSN_DELETED",
"NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
"NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
- "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
"NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
+ "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
"NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
"NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
"NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
"NOTE_REPEATED_LINE_NUMBER", "NOTE_INSN_RANGE_START",
"NOTE_INSN_RANGE_END", "NOTE_INSN_LIVE",
- "NOTE_INSN_BASIC_BLOCK"
+ "NOTE_INSN_BASIC_BLOCK", "NOTE_INSN_EXPECTED_VALUE"
};
const char * const reg_note_name[] =
diff --git a/gcc/rtl.h b/gcc/rtl.h
index e774af37ed9..48509b654f8 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -103,23 +103,12 @@ typedef union rtunion_def
typedef struct rtx_def
{
-#ifdef ONLY_INT_FIELDS
-#ifdef CODE_FIELD_BUG
- unsigned int code : 16;
-#else
- unsigned short code;
-#endif
-#else
/* The kind of expression this is. */
- enum rtx_code code : 16;
-#endif
+ ENUM_BITFIELD(rtx_code) code: 16;
/* The kind of value the expression has. */
-#ifdef ONLY_INT_FIELDS
- int mode : 8;
-#else
- enum machine_mode mode : 8;
-#endif
+ ENUM_BITFIELD(machine_mode) mode : 8;
+
/* 1 in an INSN if it can alter flow of control
within this function.
LINK_COST_ZERO in an INSN_LIST. */
@@ -189,13 +178,8 @@ typedef struct rtx_def
/* Define macros to access the `code' field of the rtx. */
-#ifdef SHORT_ENUM_BUG
-#define GET_CODE(RTX) ((enum rtx_code) ((RTX)->code))
-#define PUT_CODE(RTX, CODE) ((RTX)->code = ((short) (CODE)))
-#else
#define GET_CODE(RTX) ((RTX)->code)
#define PUT_CODE(RTX, CODE) ((RTX)->code = (CODE))
-#endif
#define GET_MODE(RTX) ((RTX)->mode)
#define PUT_MODE(RTX, MODE) ((RTX)->mode = (MODE))
@@ -577,6 +561,7 @@ extern const char * const reg_note_name[];
#define NOTE_RANGE_INFO(INSN) XCEXP(INSN, 3, NOTE)
#define NOTE_LIVE_INFO(INSN) XCEXP(INSN, 3, NOTE)
#define NOTE_BASIC_BLOCK(INSN) XCBBDEF(INSN, 3, NOTE)
+#define NOTE_EXPECTED_VALUE(INSN) XCEXP(INSN, 3, NOTE)
/* In a NOTE that is a line number, this is the line number.
Other kinds of NOTEs are identified by negative numbers here. */
@@ -595,56 +580,87 @@ extern const char * const reg_note_name[];
should add a new value here, don't forget to change the
note_insn_name array in rtl.c. */
-/* This note is used to get rid of an insn
- when it isn't safe to patch the insn out of the chain. */
-#define NOTE_INSN_DELETED -1
-#define NOTE_INSN_BLOCK_BEG -2
-#define NOTE_INSN_BLOCK_END -3
-#define NOTE_INSN_LOOP_BEG -4
-#define NOTE_INSN_LOOP_END -5
-/* This kind of note is generated at the end of the function body,
- just before the return insn or return label.
- In an optimizing compilation it is deleted by the first jump optimization,
- after enabling that optimizer to determine whether control can fall
- off the end of the function body without a return statement. */
-#define NOTE_INSN_FUNCTION_END -6
-/* This kind of note is generated just after each call to `setjmp', et al. */
-#define NOTE_INSN_SETJMP -7
-/* Generated at the place in a loop that `continue' jumps to. */
-#define NOTE_INSN_LOOP_CONT -8
-/* Generated at the start of a duplicated exit test. */
-#define NOTE_INSN_LOOP_VTOP -9
-/* This marks the point immediately after the last prologue insn. */
-#define NOTE_INSN_PROLOGUE_END -10
-/* This marks the point immediately prior to the first epilogue insn. */
-#define NOTE_INSN_EPILOGUE_BEG -11
-/* Generated in place of user-declared labels when they are deleted. */
-#define NOTE_INSN_DELETED_LABEL -12
-/* This note indicates the start of the real body of the function,
- i.e. the point just after all of the parms have been moved into
- their homes, etc. */
-#define NOTE_INSN_FUNCTION_BEG -13
-/* These note where exception handling regions begin and end. */
-#define NOTE_INSN_EH_REGION_BEG -14
-#define NOTE_INSN_EH_REGION_END -15
-/* Generated whenever a duplicate line number note is output. For example,
- one is output after the end of an inline function, in order to prevent
- the line containing the inline call from being counted twice in gcov. */
-#define NOTE_REPEATED_LINE_NUMBER -16
-
-/* Start/end of a live range region, where pseudos allocated on the stack can
- be allocated to temporary registers. */
-#define NOTE_INSN_RANGE_START -17
-#define NOTE_INSN_RANGE_END -18
-/* Record which registers are currently live. */
-#define NOTE_INSN_LIVE -19
-/* Record the struct for the following basic block. */
-#define NOTE_INSN_BASIC_BLOCK -20
+enum insn_note
+{
+ /* Keep all of these numbers negative. Adjust as needed. */
+ NOTE_INSN_BIAS = -100,
+
+ /* This note is used to get rid of an insn
+ when it isn't safe to patch the insn out of the chain. */
+ NOTE_INSN_DELETED,
+
+ /* These are used to mark the beginning and end of a lexical block.
+ See NOTE_BLOCK, identify_blocks and reorder_blocks. */
+ NOTE_INSN_BLOCK_BEG,
+ NOTE_INSN_BLOCK_END,
+
+ /* These mark the extremes of a loop. */
+ NOTE_INSN_LOOP_BEG,
+ NOTE_INSN_LOOP_END,
+
+ /* Generated at the place in a loop that `continue' jumps to. */
+ NOTE_INSN_LOOP_CONT,
+ /* Generated at the start of a duplicated exit test. */
+ NOTE_INSN_LOOP_VTOP,
+
+ /* This kind of note is generated at the end of the function body,
+ just before the return insn or return label. In an optimizing
+ compilation it is deleted by the first jump optimization, after
+ enabling that optimizer to determine whether control can fall
+ off the end of the function body without a return statement. */
+ NOTE_INSN_FUNCTION_END,
+
+ /* This kind of note is generated just after each call to `setjmp',
+ and similar functions that can return twice. */
+ NOTE_INSN_SETJMP,
+
+ /* This marks the point immediately after the last prologue insn. */
+ NOTE_INSN_PROLOGUE_END,
+
+ /* This marks the point immediately prior to the first epilogue insn. */
+ NOTE_INSN_EPILOGUE_BEG,
+
+ /* Generated in place of user-declared labels when they are deleted. */
+ NOTE_INSN_DELETED_LABEL,
+
+ /* This note indicates the start of the real body of the function,
+ i.e. the point just after all of the parms have been moved into
+ their homes, etc. */
+ NOTE_INSN_FUNCTION_BEG,
+
+ /* These note where exception handling regions begin and end.
+ Uses NOTE_EH_HANDLER to identify the region in question. */
+ NOTE_INSN_EH_REGION_BEG,
+ NOTE_INSN_EH_REGION_END,
+
+ /* Generated whenever a duplicate line number note is output. For example,
+ one is output after the end of an inline function, in order to prevent
+ the line containing the inline call from being counted twice in gcov. */
+ NOTE_REPEATED_LINE_NUMBER,
+
+ /* Start/end of a live range region, where pseudos allocated on the stack
+ can be allocated to temporary registers. Uses NOTE_RANGE_INFO. */
+ NOTE_INSN_RANGE_START,
+ NOTE_INSN_RANGE_END,
+
+ /* Record which registers are currently live. Uses NOTE_LIVE_INFO. */
+ NOTE_INSN_LIVE,
+
+ /* Record the struct for the following basic block. Uses NOTE_BASIC_BLOCK. */
+ NOTE_INSN_BASIC_BLOCK,
+
+ /* Record the expected value of a register at a location. Uses
+ NOTE_EXPECTED_VALUE; stored as (eq (reg) (const_int)). */
+ NOTE_INSN_EXPECTED_VALUE,
+
+ NOTE_INSN_MAX
+};
/* Names for NOTE insn's other than line numbers. */
-extern const char * const note_insn_name[];
-#define GET_NOTE_INSN_NAME(NOTE_CODE) (note_insn_name[-(NOTE_CODE)])
+extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
+#define GET_NOTE_INSN_NAME(NOTE_CODE) \
+ (note_insn_name[(NOTE_CODE) - NOTE_INSN_BIAS])
/* The name of a label, in case it corresponds to an explicit label
in the input source code. */
diff --git a/gcc/scan-decls.c b/gcc/scan-decls.c
index a0b8de0664f..3c33a1cc659 100644
--- a/gcc/scan-decls.c
+++ b/gcc/scan-decls.c
@@ -48,9 +48,9 @@ skip_to_closing_brace (pfile)
enum cpp_ttype token = cpp_get_token (pfile);
if (token == CPP_EOF)
break;
- if (token == CPP_LBRACE)
+ if (token == CPP_OPEN_BRACE)
nesting++;
- if (token == CPP_RBRACE && --nesting == 0)
+ if (token == CPP_CLOSE_BRACE && --nesting == 0)
break;
}
}
@@ -101,7 +101,7 @@ scan_decls (pfile, argc, argv)
current_extern_C = 0;
saw_extern = 0;
saw_inline = 0;
- if (token == CPP_RBRACE)
+ if (token == CPP_OPEN_BRACE)
{
/* Pop an 'extern "C"' nesting level, if appropriate. */
if (extern_C_braces_length
@@ -110,7 +110,7 @@ scan_decls (pfile, argc, argv)
brace_nesting--;
goto new_statement;
}
- if (token == CPP_LBRACE)
+ if (token == CPP_OPEN_BRACE)
{
brace_nesting++;
goto new_statement;
@@ -128,7 +128,7 @@ scan_decls (pfile, argc, argv)
{
switch (token)
{
- case CPP_LPAREN:
+ case CPP_OPEN_PAREN:
/* Looks like this is the start of a formal parameter list. */
if (prev_id_start)
{
@@ -139,9 +139,9 @@ scan_decls (pfile, argc, argv)
for (;;)
{
token = cpp_get_token (pfile);
- if (token == CPP_LPAREN)
+ if (token == CPP_OPEN_PAREN)
nesting++;
- else if (token == CPP_RPAREN)
+ else if (token == CPP_CLOSE_PAREN)
{
nesting--;
if (nesting == 0)
@@ -149,7 +149,7 @@ scan_decls (pfile, argc, argv)
}
else if (token == CPP_EOF)
break;
- else if (token == CPP_NAME || token == CPP_3DOTS)
+ else if (token == CPP_NAME || token == CPP_ELLIPSIS)
have_arg_list = 1;
}
recognized_function (pfile->token_buffer + prev_id_start,
@@ -161,7 +161,7 @@ scan_decls (pfile, argc, argv)
have_arg_list,
fbuf->nominal_fname, func_lineno);
token = cpp_get_non_space_token (pfile);
- if (token == CPP_LBRACE)
+ if (token == CPP_OPEN_BRACE)
{
/* skip body of (normally) inline function */
skip_to_closing_brace (pfile);
@@ -218,7 +218,7 @@ scan_decls (pfile, argc, argv)
CPP_SET_WRITTEN (pfile, start_written);
current_extern_C = 1;
token = cpp_get_non_space_token (pfile);
- if (token == CPP_LBRACE)
+ if (token == CPP_OPEN_BRACE)
{
brace_nesting++;
extern_C_braces[extern_C_braces_length++]
@@ -238,7 +238,7 @@ scan_decls (pfile, argc, argv)
case CPP_EOF:
return 0;
- case CPP_LBRACE: case CPP_RBRACE: case CPP_DIRECTIVE:
+ case CPP_OPEN_BRACE: case CPP_CLOSE_BRACE: case CPP_DIRECTIVE:
goto new_statement; /* handle_statement? */
case CPP_HSPACE: case CPP_VSPACE: case CPP_COMMENT: case CPP_POP:
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 9e2674304ba..a9595573ee7 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1,4 +1,4 @@
-/* Common subexpression elimination for GNU compiler.
+/* RTL simplification functions for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000 Free Software Foundation, Inc.
@@ -21,7 +21,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
-/* stdio.h must precede rtl.h for FFS. */
#include "system.h"
#include <setjmp.h>
@@ -94,10 +93,94 @@ Boston, MA 02111-1307, USA. */
|| GET_CODE (X) == ADDRESSOF)
-static rtx simplify_plus_minus PARAMS ((enum rtx_code, enum machine_mode,
- rtx, rtx));
-static void check_fold_consts PARAMS ((PTR));
+static rtx simplify_plus_minus PARAMS ((enum rtx_code,
+ enum machine_mode, rtx, rtx));
+static void check_fold_consts PARAMS ((PTR));
+static int entry_and_rtx_equal_p PARAMS ((const void *, const void *));
+static unsigned int get_value_hash PARAMS ((const void *));
+static struct elt_list *new_elt_list PARAMS ((struct elt_list *,
+ cselib_val *));
+static struct elt_loc_list *new_elt_loc_list PARAMS ((struct elt_loc_list *,
+ rtx));
+static void unchain_one_value PARAMS ((cselib_val *));
+static void unchain_one_elt_list PARAMS ((struct elt_list **));
+static void unchain_one_elt_loc_list PARAMS ((struct elt_loc_list **));
+static void clear_table PARAMS ((void));
+static int check_value_useless PARAMS ((cselib_val *));
+static int discard_useless_locs PARAMS ((void **, void *));
+static int discard_useless_values PARAMS ((void **, void *));
+static void remove_useless_values PARAMS ((void));
+static unsigned int hash_rtx PARAMS ((rtx, enum machine_mode, int));
+static cselib_val *new_cselib_val PARAMS ((unsigned int,
+ enum machine_mode));
+static void add_mem_for_addr PARAMS ((cselib_val *, cselib_val *,
+ rtx));
+static cselib_val *cselib_lookup_mem PARAMS ((rtx, int));
+static rtx cselib_subst_to_values PARAMS ((rtx));
+static void cselib_invalidate_regno PARAMS ((unsigned int,
+ enum machine_mode));
+static int cselib_mem_conflict_p PARAMS ((rtx, rtx));
+static int cselib_invalidate_mem_1 PARAMS ((void **, void *));
+static void cselib_invalidate_mem PARAMS ((rtx));
+static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *));
+static void cselib_record_set PARAMS ((rtx, cselib_val *,
+ cselib_val *));
+static void cselib_record_sets PARAMS ((rtx));
+
+/* There are three ways in which cselib can look up an rtx:
+ - for a REG, the reg_values table (which is indexed by regno) is used
+ - for a MEM, we recursively look up its address and then follow the
+ addr_list of that value
+ - for everything else, we compute a hash value and go through the hash
+ table. Since different rtx's can still have the same hash value,
+ this involves walking the table entries for a given value and comparing
+ the locations of the entries with the rtx we are looking up. */
+
+/* A table that enables us to look up elts by their value. */
+static htab_t hash_table;
+
+/* This is a global so we don't have to pass this through every function.
+ It is used in new_elt_loc_list to set SETTING_INSN. */
+static rtx cselib_current_insn;
+
+/* Every new unknown value gets a unique number. */
+static unsigned int next_unknown_value;
+/* The number of registers we had when the varrays were last resized. */
+static unsigned int cselib_nregs;
+
+/* Count values without known locations. Whenever this grows too big, we
+ remove these useless values from the table. */
+static int n_useless_values;
+
+/* Number of useless values before we remove them from the hash table. */
+#define MAX_USELESS_VALUES 32
+
+/* This table maps from register number to values. It does not contain
+ pointers to cselib_val structures, but rather elt_lists. The purpose is
+ to be able to refer to the same register in different modes. */
+static varray_type reg_values;
+#define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
+
+/* We pass this to cselib_invalidate_mem to invalidate all of
+ memory for a non-const call instruction. */
+static rtx callmem;
+
+/* Memory for our structures is allocated from this obstack. */
+static struct obstack cselib_obstack;
+
+/* Used to quickly free all memory. */
+static char *cselib_startobj;
+
+/* Caches for unused structures. */
+static cselib_val *empty_vals;
+static struct elt_list *empty_elt_lists;
+static struct elt_loc_list *empty_elt_loc_lists;
+
+/* Set by discard_useless_locs if it deleted the last location of any
+ value. */
+static int values_became_useless;
+
/* Make a binary operation by properly ordering the operands and
seeing if the expression folds. */
@@ -1809,7 +1892,7 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
enum machine_mode mode, op0_mode;
rtx op0, op1, op2;
{
- int width = GET_MODE_BITSIZE (mode);
+ unsigned int width = GET_MODE_BITSIZE (mode);
/* VOIDmode means "infinite" precision. */
if (width == 0)
@@ -1872,9 +1955,10 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
return op2;
else if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
{
- rtx temp;
- temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
- XEXP (op0, 0), XEXP (op0, 1));
+ rtx temp
+ = simplify_relational_operation (GET_CODE (op0), op0_mode,
+ XEXP (op0, 0), XEXP (op0, 1));
+
/* See if any simplifications were possible. */
if (temp == const0_rtx)
return op2;
@@ -1962,93 +2046,17 @@ simplify_rtx (x)
}
}
-static int entry_and_rtx_equal_p PARAMS ((const void *, const void *));
-static unsigned int get_value_hash PARAMS ((const void *));
-static struct elt_list *new_elt_list PARAMS ((struct elt_list *, cselib_val *));
-static struct elt_loc_list *new_elt_loc_list PARAMS ((struct elt_loc_list *, rtx));
-static void unchain_one_value PARAMS ((cselib_val *));
-static void unchain_one_elt_list PARAMS ((struct elt_list **));
-static void unchain_one_elt_loc_list PARAMS ((struct elt_loc_list **));
-static void clear_table PARAMS ((void));
-static int check_value_useless PARAMS ((cselib_val *));
-static int discard_useless_locs PARAMS ((void **, void *));
-static int discard_useless_values PARAMS ((void **, void *));
-static void remove_useless_values PARAMS ((void));
-static unsigned int hash_rtx PARAMS ((rtx, enum machine_mode, int));
-static cselib_val *new_cselib_val PARAMS ((unsigned int,
- enum machine_mode));
-static void add_mem_for_addr PARAMS ((cselib_val *, cselib_val *,
- rtx));
-static cselib_val *cselib_lookup_mem PARAMS ((rtx, int));
-static rtx cselib_subst_to_values PARAMS ((rtx));
-static void cselib_invalidate_regno PARAMS ((unsigned int,
- enum machine_mode));
-static int cselib_mem_conflict_p PARAMS ((rtx, rtx));
-static int cselib_invalidate_mem_1 PARAMS ((void **, void *));
-static void cselib_invalidate_mem PARAMS ((rtx));
-static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *));
-static void cselib_record_set PARAMS ((rtx, cselib_val *,
- cselib_val *));
-static void cselib_record_sets PARAMS ((rtx));
-
-/* There are three ways in which cselib can look up an rtx:
- - for a REG, the reg_values table (which is indexed by regno) is used
- - for a MEM, we recursively look up its address and then follow the
- addr_list of that value
- - for everything else, we compute a hash value and go through the hash
- table. Since different rtx's can still have the same hash value,
- this involves walking the table entries for a given value and comparing
- the locations of the entries with the rtx we are looking up. */
-
-/* A table that enables us to look up elts by their value. */
-static htab_t hash_table;
-
-/* This is a global so we don't have to pass this through every function.
- It is used in new_elt_loc_list to set SETTING_INSN. */
-static rtx cselib_current_insn;
-
-/* Every new unknown value gets a unique number. */
-static unsigned int next_unknown_value;
-
-/* The number of registers we had when the varrays were last resized. */
-static int cselib_nregs;
-
-/* Count values without known locations. Whenever this grows too big, we
- remove these useless values from the table. */
-static int n_useless_values;
-
-/* Number of useless values before we remove them from the hash table. */
-#define MAX_USELESS_VALUES 32
-
-/* This table maps from register number to values. It does not contain
- pointers to cselib_val structures, but rather elt_lists. The purpose is
- to be able to refer to the same register in different modes. */
-static varray_type reg_values;
-#define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
-
-/* We pass this to cselib_invalidate_mem to invalidate all of
- memory for a non-const call instruction. */
-static rtx callmem;
-
-/* Memory for our structures is allocated from this obstack. */
-static struct obstack cselib_obstack;
-
-/* Used to quickly free all memory. */
-static char *cselib_startobj;
-
-/* Caches for unused structures. */
-static cselib_val *empty_vals;
-static struct elt_list *empty_elt_lists;
-static struct elt_loc_list *empty_elt_loc_lists;
/* Allocate a struct elt_list and fill in its two elements with the
arguments. */
+
static struct elt_list *
new_elt_list (next, elt)
struct elt_list *next;
cselib_val *elt;
{
struct elt_list *el = empty_elt_lists;
+
if (el)
empty_elt_lists = el->next;
else
@@ -2061,12 +2069,14 @@ new_elt_list (next, elt)
/* Allocate a struct elt_loc_list and fill in its two elements with the
arguments. */
+
static struct elt_loc_list *
new_elt_loc_list (next, loc)
struct elt_loc_list *next;
rtx loc;
{
struct elt_loc_list *el = empty_elt_loc_lists;
+
if (el)
empty_elt_loc_lists = el->next;
else
@@ -2080,22 +2090,26 @@ new_elt_loc_list (next, loc)
/* The elt_list at *PL is no longer needed. Unchain it and free its
storage. */
+
static void
unchain_one_elt_list (pl)
struct elt_list **pl;
{
struct elt_list *l = *pl;
+
*pl = l->next;
l->next = empty_elt_lists;
empty_elt_lists = l;
}
/* Likewise for elt_loc_lists. */
+
static void
unchain_one_elt_loc_list (pl)
struct elt_loc_list **pl;
{
struct elt_loc_list *l = *pl;
+
*pl = l->next;
l->next = empty_elt_loc_lists;
empty_elt_loc_lists = l;
@@ -2103,6 +2117,7 @@ unchain_one_elt_loc_list (pl)
/* Likewise for cselib_vals. This also frees the addr_list associated with
V. */
+
static void
unchain_one_value (v)
cselib_val *v;
@@ -2116,10 +2131,12 @@ unchain_one_value (v)
/* Remove all entries from the hash table. Also used during
initialization. */
+
static void
clear_table ()
{
- int i;
+ unsigned int i;
+
for (i = 0; i < cselib_nregs; i++)
REG_VALUES (i) = 0;
@@ -2136,25 +2153,28 @@ clear_table ()
/* The equality test for our hash table. The first argument ENTRY is a table
element (i.e. a cselib_val), while the second arg X is an rtx. */
+
static int
entry_and_rtx_equal_p (entry, x_arg)
const void *entry, *x_arg;
{
struct elt_loc_list *l;
- const cselib_val *v = (const cselib_val *)entry;
- rtx x = (rtx)x_arg;
+ const cselib_val *v = (const cselib_val *) entry;
+ rtx x = (rtx) x_arg;
/* We don't guarantee that distinct rtx's have different hash values,
so we need to do a comparison. */
for (l = v->locs; l; l = l->next)
if (rtx_equal_for_cselib_p (l->loc, x))
return 1;
+
return 0;
}
/* The hash function for our hash table. The value is always computed with
hash_rtx when adding an element; this function just extracts the hash
value from a cselib_val structure. */
+
static unsigned int
get_value_hash (entry)
const void *entry;
@@ -2166,6 +2186,7 @@ get_value_hash (entry)
/* If there are no more locations that hold a value, the value has become
useless. See whether that is the case for V. Return 1 if this has
just become useless. */
+
static int
check_value_useless (v)
cselib_val *v;
@@ -2186,6 +2207,7 @@ check_value_useless (v)
only return true for values which point to a cselib_val whose value
element has been set to zero, which implies the cselib_val will be
removed. */
+
int
references_value_p (x, only_useless)
rtx x;
@@ -2193,7 +2215,7 @@ references_value_p (x, only_useless)
{
enum rtx_code code = GET_CODE (x);
const char *fmt = GET_RTX_FORMAT (code);
- int i;
+ int i, j;
if (GET_CODE (x) == VALUE
&& (! only_useless || CSELIB_VAL_PTR (x)->value == 0))
@@ -2201,31 +2223,21 @@ references_value_p (x, only_useless)
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
- if (fmt[i] == 'e')
- {
- if (references_value_p (XEXP (x, i), only_useless))
- return 1;
- }
+ if (fmt[i] == 'e' && references_value_p (XEXP (x, i), only_useless))
+ return 1;
else if (fmt[i] == 'E')
- {
- int j;
-
- for (j = 0; j < XVECLEN (x, i); j++)
- if (references_value_p (XVECEXP (x, i, j), only_useless))
- return 1;
- }
+ for (j = 0; j < XVECLEN (x, i); j++)
+ if (references_value_p (XVECEXP (x, i, j), only_useless))
+ return 1;
}
return 0;
}
-/* Set by discard_useless_locs if it deleted the last location of any
- value. */
-static int values_became_useless;
-
/* For all locations found in X, delete locations that reference useless
values (i.e. values without any location). Called through
htab_traverse. */
+
static int
discard_useless_locs (x, info)
void **x;
@@ -2241,6 +2253,7 @@ discard_useless_locs (x, info)
else
p = &(*p)->next;
}
+
if (check_value_useless (v))
values_became_useless = 1;
@@ -2262,11 +2275,13 @@ discard_useless_values (x, info)
unchain_one_value (v);
n_useless_values--;
}
+
return 1;
}
/* Clean out useless values (i.e. those which no longer have locations
associated with them) from the hash table. */
+
static void
remove_useless_values ()
{
@@ -2288,6 +2303,7 @@ remove_useless_values ()
/* Return nonzero if we can prove that X and Y contain the same value, taking
our gathered information into account. */
+
int
rtx_equal_for_cselib_p (x, y)
rtx x, y;
@@ -2299,12 +2315,15 @@ rtx_equal_for_cselib_p (x, y)
if (GET_CODE (x) == REG || GET_CODE (x) == MEM)
{
cselib_val *e = cselib_lookup (x, VOIDmode, 0);
+
if (e)
x = e->u.val_rtx;
}
+
if (GET_CODE (y) == REG || GET_CODE (y) == MEM)
{
cselib_val *e = cselib_lookup (y, VOIDmode, 0);
+
if (e)
y = e->u.val_rtx;
}
@@ -2327,8 +2346,7 @@ rtx_equal_for_cselib_p (x, y)
/* Avoid infinite recursion. */
if (GET_CODE (t) == REG || GET_CODE (t) == MEM)
continue;
-
- if (rtx_equal_for_cselib_p (t, y))
+ else if (rtx_equal_for_cselib_p (t, y))
return 1;
}
@@ -2346,16 +2364,14 @@ rtx_equal_for_cselib_p (x, y)
if (GET_CODE (t) == REG || GET_CODE (t) == MEM)
continue;
-
- if (rtx_equal_for_cselib_p (x, t))
+ else if (rtx_equal_for_cselib_p (x, t))
return 1;
}
return 0;
}
- if (GET_CODE (x) != GET_CODE (y)
- || GET_MODE (x) != GET_MODE (y))
+ if (GET_CODE (x) != GET_CODE (y) || GET_MODE (x) != GET_MODE (y))
return 0;
/* This won't be handled correctly by the code below. */
@@ -2368,6 +2384,7 @@ rtx_equal_for_cselib_p (x, y)
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
int j;
+
switch (fmt[i])
{
case 'w':
@@ -2431,6 +2448,7 @@ rtx_equal_for_cselib_p (x, y)
CREATE is nonzero, table elts are created for regs and mem.
MODE is used in hashing for CONST_INTs only;
otherwise the mode of X is used. */
+
static unsigned int
hash_rtx (x, mode, create)
rtx x;
@@ -2455,15 +2473,13 @@ hash_rtx (x, mode, create)
e = cselib_lookup (x, GET_MODE (x), create);
if (! e)
return 0;
+
hash += e->value;
return hash;
case CONST_INT:
- {
- unsigned HOST_WIDE_INT tem = INTVAL (x);
- hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + tem;
- return hash ? hash : CONST_INT;
- }
+ hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + INTVAL (x);
+ return hash ? hash : CONST_INT;
case CONST_DOUBLE:
/* This is like the general case, except that it only counts
@@ -2471,10 +2487,7 @@ hash_rtx (x, mode, create)
hash += (unsigned) code + (unsigned) GET_MODE (x);
if (GET_MODE (x) != VOIDmode)
for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++)
- {
- unsigned HOST_WIDE_INT tem = XWINT (x, i);
- hash += tem;
- }
+ hash += XWINT (x, i);
else
hash += ((unsigned) CONST_DOUBLE_LOW (x)
+ (unsigned) CONST_DOUBLE_HIGH (x));
@@ -2517,8 +2530,8 @@ hash_rtx (x, mode, create)
{
if (fmt[i] == 'e')
{
- unsigned int tem_hash;
rtx tem = XEXP (x, i);
+ unsigned int tem_hash;
/* If we are about to do the last recursive call
needed at this level, change it into iteration.
@@ -2528,57 +2541,63 @@ hash_rtx (x, mode, create)
x = tem;
goto repeat;
}
+
tem_hash = hash_rtx (tem, 0, create);
if (tem_hash == 0)
return 0;
+
hash += tem_hash;
}
else if (fmt[i] == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
{
unsigned int tem_hash = hash_rtx (XVECEXP (x, i, j), 0, create);
+
if (tem_hash == 0)
return 0;
+
hash += tem_hash;
}
else if (fmt[i] == 's')
{
const unsigned char *p = (const unsigned char *) XSTR (x, i);
+
if (p)
while (*p)
hash += *p++;
}
else if (fmt[i] == 'i')
- {
- unsigned int tem = XINT (x, i);
- hash += tem;
- }
+ hash += XINT (x, i);
else if (fmt[i] == '0' || fmt[i] == 't')
/* unused */;
else
abort ();
}
+
return hash ? hash : 1 + GET_CODE (x);
}
/* Create a new value structure for VALUE and initialize it. The mode of the
value is MODE. */
+
static cselib_val *
new_cselib_val (value, mode)
unsigned int value;
enum machine_mode mode;
{
cselib_val *e = empty_vals;
+
if (e)
empty_vals = e->u.next_free;
else
e = (cselib_val *) obstack_alloc (&cselib_obstack, sizeof (cselib_val));
+
if (value == 0)
abort ();
+
e->value = value;
e->u.val_rtx = gen_rtx_VALUE (mode);
CSELIB_VAL_PTR (e->u.val_rtx) = e;
-
e->addr_list = 0;
e->locs = 0;
return e;
@@ -2587,6 +2606,7 @@ new_cselib_val (value, mode)
/* ADDR_ELT is a value that is used as address. MEM_ELT is the value that
contains the data at this address. X is a MEM that represents the
value. Update the two value structures to represent this situation. */
+
static void
add_mem_for_addr (addr_elt, mem_elt, x)
cselib_val *addr_elt, *mem_elt;
@@ -2612,6 +2632,7 @@ add_mem_for_addr (addr_elt, mem_elt, x)
/* Subroutine of cselib_lookup. Return a value for X, which is a MEM rtx.
If CREATE, make a new one if we haven't seen it before. */
+
static cselib_val *
cselib_lookup_mem (x, create)
rtx x;
@@ -2622,9 +2643,8 @@ cselib_lookup_mem (x, create)
cselib_val *mem_elt;
struct elt_list *l;
- if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode)
- return 0;
- if (FLOAT_MODE_P (GET_MODE (x)) && flag_float_store)
+ if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode
+ || (FLOAT_MODE_P (GET_MODE (x)) && flag_float_store))
return 0;
/* Look up the value for the address. */
@@ -2636,11 +2656,13 @@ cselib_lookup_mem (x, create)
for (l = addr->addr_list; l; l = l->next)
if (GET_MODE (l->elt->u.val_rtx) == GET_MODE (x))
return l->elt;
+
if (! create)
return 0;
+
mem_elt = new_cselib_val (++next_unknown_value, GET_MODE (x));
add_mem_for_addr (addr, mem_elt, x);
- slot = htab_find_slot_with_hash (hash_table, x, mem_elt->value, 1);
+ slot = htab_find_slot_with_hash (hash_table, x, mem_elt->value, INSERT);
*slot = mem_elt;
return mem_elt;
}
@@ -2650,6 +2672,7 @@ cselib_lookup_mem (x, create)
to registers and memory.
X isn't actually modified; if modifications are needed, new rtl is
allocated. However, the return value can share rtl with X. */
+
static rtx
cselib_subst_to_values (x)
rtx x;
@@ -2664,10 +2687,10 @@ cselib_subst_to_values (x)
switch (code)
{
case REG:
- i = REGNO (x);
- for (l = REG_VALUES (i); l; l = l->next)
+ for (l = REG_VALUES (REGNO (x)); l; l = l->next)
if (GET_MODE (l->elt->u.val_rtx) == GET_MODE (x))
return l->elt->u.val_rtx;
+
abort ();
case MEM:
@@ -2691,8 +2714,10 @@ cselib_subst_to_values (x)
if (fmt[i] == 'e')
{
rtx t = cselib_subst_to_values (XEXP (x, i));
+
if (t != XEXP (x, i) && x == copy)
copy = shallow_copy_rtx (x);
+
XEXP (copy, i) = t;
}
else if (fmt[i] == 'E')
@@ -2702,18 +2727,22 @@ cselib_subst_to_values (x)
for (j = 0; j < XVECLEN (x, i); j++)
{
rtx t = cselib_subst_to_values (XVECEXP (x, i, j));
+
if (t != XVECEXP (x, i, j) && XVEC (x, i) == XVEC (copy, i))
{
if (x == copy)
copy = shallow_copy_rtx (x);
+
XVEC (copy, i) = rtvec_alloc (XVECLEN (x, i));
for (k = 0; k < j; k++)
XVECEXP (copy, i, k) = XVECEXP (x, i, k);
}
+
XVECEXP (copy, i, j) = t;
}
}
}
+
return copy;
}
@@ -2721,6 +2750,7 @@ cselib_subst_to_values (x)
If CREATE is zero, we return NULL if we don't know the value. Otherwise,
we create a new one if possible, using mode MODE if X doesn't have a mode
(i.e. because it's a constant). */
+
cselib_val *
cselib_lookup (x, mode, create)
rtx x;
@@ -2740,16 +2770,19 @@ cselib_lookup (x, mode, create)
if (GET_CODE (x) == REG)
{
struct elt_list *l;
- int i = REGNO (x);
+ unsigned int i = REGNO (x);
+
for (l = REG_VALUES (i); l; l = l->next)
if (mode == GET_MODE (l->elt->u.val_rtx))
return l->elt;
+
if (! create)
return 0;
+
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
e->locs = new_elt_loc_list (e->locs, x);
REG_VALUES (i) = new_elt_list (REG_VALUES (i), e);
- slot = htab_find_slot_with_hash (hash_table, x, e->value, 1);
+ slot = htab_find_slot_with_hash (hash_table, x, e->value, INSERT);
*slot = e;
return e;
}
@@ -2762,14 +2795,17 @@ cselib_lookup (x, mode, create)
if (! hashval)
return 0;
- slot = htab_find_slot_with_hash (hash_table, x, hashval, create);
+ slot = htab_find_slot_with_hash (hash_table, x, hashval,
+ create ? INSERT : NO_INSERT);
if (slot == 0)
return 0;
+
e = (cselib_val *) *slot;
if (e)
return e;
e = new_cselib_val (hashval, mode);
+
/* We have to fill the slot before calling cselib_subst_to_values:
the hash table is inconsistent until we do so, and
cselib_subst_to_values will need to do lookups. */
@@ -2841,6 +2877,7 @@ cselib_invalidate_regno (regno, mode)
break;
}
}
+
check_value_useless (v);
}
}
@@ -2848,6 +2885,7 @@ cselib_invalidate_regno (regno, mode)
/* The memory at address MEM_BASE is being changed.
Return whether this change will invalidate VAL. */
+
static int
cselib_mem_conflict_p (mem_base, val)
rtx mem_base;
@@ -2855,7 +2893,7 @@ cselib_mem_conflict_p (mem_base, val)
{
enum rtx_code code;
const char *fmt;
- int i;
+ int i, j;
code = GET_CODE (val);
switch (code)
@@ -2874,10 +2912,10 @@ cselib_mem_conflict_p (mem_base, val)
case MEM:
if (GET_MODE (mem_base) == BLKmode
- || GET_MODE (val) == BLKmode)
- return 1;
- if (anti_dependence (val, mem_base))
+ || GET_MODE (val) == BLKmode
+ || anti_dependence (val, mem_base))
return 1;
+
/* The address may contain nested MEMs. */
break;
@@ -2886,7 +2924,6 @@ cselib_mem_conflict_p (mem_base, val)
}
fmt = GET_RTX_FORMAT (code);
-
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
@@ -2895,13 +2932,9 @@ cselib_mem_conflict_p (mem_base, val)
return 1;
}
else if (fmt[i] == 'E')
- {
- int j;
-
- for (j = 0; j < XVECLEN (val, i); j++)
- if (cselib_mem_conflict_p (mem_base, XVECEXP (val, i, j)))
- return 1;
- }
+ for (j = 0; j < XVECLEN (val, i); j++)
+ if (cselib_mem_conflict_p (mem_base, XVECEXP (val, i, j)))
+ return 1;
}
return 0;
@@ -2909,6 +2942,7 @@ cselib_mem_conflict_p (mem_base, val)
/* For the value found in SLOT, walk its locations to determine if any overlap
INFO (which is a MEM rtx). */
+
static int
cselib_invalidate_mem_1 (slot, info)
void **slot;
@@ -2920,9 +2954,9 @@ cselib_invalidate_mem_1 (slot, info)
while (*p)
{
+ rtx x = (*p)->loc;
cselib_val *addr;
struct elt_list **mem_chain;
- rtx x = (*p)->loc;
/* MEMs may occur in locations only at the top level; below
that every MEM or REG is substituted by its VALUE. */
@@ -2945,10 +2979,13 @@ cselib_invalidate_mem_1 (slot, info)
unchain_one_elt_list (mem_chain);
break;
}
+
mem_chain = &(*mem_chain)->next;
}
+
unchain_one_elt_loc_list (p);
}
+
check_value_useless (v);
return 1;
}
@@ -2956,6 +2993,7 @@ cselib_invalidate_mem_1 (slot, info)
/* Invalidate any locations in the table which are changed because of a
store to MEM_RTX. If this is called because of a non-const call
instruction, MEM_RTX is (mem:BLK const0_rtx). */
+
static void
cselib_invalidate_mem (mem_rtx)
rtx mem_rtx;
@@ -2966,16 +3004,15 @@ cselib_invalidate_mem (mem_rtx)
/* Invalidate DEST, which is being assigned to or clobbered. The second and
the third parameter exist so that this function can be passed to
note_stores; they are ignored. */
+
static void
cselib_invalidate_rtx (dest, ignore, data)
rtx dest;
rtx ignore ATTRIBUTE_UNUSED;
void *data ATTRIBUTE_UNUSED;
{
- while (GET_CODE (dest) == STRICT_LOW_PART
- || GET_CODE (dest) == SIGN_EXTRACT
- || GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SUBREG)
+ while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT
+ || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG)
dest = XEXP (dest, 0);
if (GET_CODE (dest) == REG)
@@ -3086,11 +3123,13 @@ cselib_record_sets (insn)
}
/* Record the effects of INSN. */
+
void
cselib_process_insn (insn)
rtx insn;
{
int i;
+ rtx x;
cselib_current_insn = insn;
@@ -3111,6 +3150,7 @@ cselib_process_insn (insn)
cselib_current_insn = 0;
return;
}
+
/* If this is a call instruction, forget anything stored in a
call clobbered register, or, if this is not a const call, in
memory. */
@@ -3130,26 +3170,17 @@ cselib_process_insn (insn)
/* Clobber any registers which appear in REG_INC notes. We
could keep track of the changes to their values, but it is
unlikely to help. */
- {
- rtx x;
-
- for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
- if (REG_NOTE_KIND (x) == REG_INC)
- cselib_invalidate_rtx (XEXP (x, 0), NULL_RTX, NULL);
- }
+ for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
+ if (REG_NOTE_KIND (x) == REG_INC)
+ cselib_invalidate_rtx (XEXP (x, 0), NULL_RTX, NULL);
#endif
/* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only
after we have processed the insn. */
if (GET_CODE (insn) == CALL_INSN)
- {
- rtx x;
-
- for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
- if (GET_CODE (XEXP (x, 0)) == CLOBBER)
- cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0), NULL_RTX,
- NULL);
- }
+ for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
+ if (GET_CODE (XEXP (x, 0)) == CLOBBER)
+ cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0), NULL_RTX, NULL);
cselib_current_insn = 0;
@@ -3159,18 +3190,22 @@ cselib_process_insn (insn)
/* Make sure our varrays are big enough. Not called from any cselib routines;
it must be called by the user if it allocated new registers. */
+
void
cselib_update_varray_sizes ()
{
- int nregs = max_reg_num ();
+ unsigned int nregs = max_reg_num ();
+
if (nregs == cselib_nregs)
return;
+
cselib_nregs = nregs;
VARRAY_GROW (reg_values, nregs);
}
/* Initialize cselib for one pass. The caller must also call
init_alias_analysis. */
+
void
cselib_init ()
{
@@ -3178,6 +3213,7 @@ cselib_init ()
if (! callmem)
{
extern struct obstack permanent_obstack;
+
gcc_obstack_init (&cselib_obstack);
cselib_startobj = obstack_alloc (&cselib_obstack, 0);
@@ -3194,6 +3230,7 @@ cselib_init ()
}
/* Called when the current user is done with cselib. */
+
void
cselib_finish ()
{
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 8516e368964..5bad3397eb2 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -430,6 +430,7 @@ static void mark_cond_nesting PARAMS ((struct nesting *));
static void mark_loop_nesting PARAMS ((struct nesting *));
static void mark_block_nesting PARAMS ((struct nesting *));
static void mark_case_nesting PARAMS ((struct nesting *));
+static void mark_case_node PARAMS ((struct case_node *));
static void mark_goto_fixup PARAMS ((struct goto_fixup *));
@@ -509,28 +510,35 @@ mark_case_nesting (n)
{
while (n)
{
- struct case_node *node;
-
ggc_mark_rtx (n->exit_label);
ggc_mark_rtx (n->data.case_stmt.start);
- node = n->data.case_stmt.case_list;
- while (node)
- {
- ggc_mark_tree (node->low);
- ggc_mark_tree (node->high);
- ggc_mark_tree (node->code_label);
- node = node->right;
- }
-
ggc_mark_tree (n->data.case_stmt.default_label);
ggc_mark_tree (n->data.case_stmt.index_expr);
ggc_mark_tree (n->data.case_stmt.nominal_type);
+ mark_case_node (n->data.case_stmt.case_list);
n = n->next;
}
}
+/* Mark C for GC. */
+
+static void
+mark_case_node (c)
+ struct case_node *c;
+{
+ if (c != 0)
+ {
+ ggc_mark_tree (c->low);
+ ggc_mark_tree (c->high);
+ ggc_mark_tree (c->code_label);
+
+ mark_case_node (c->right);
+ mark_case_node (c->left);
+ }
+}
+
/* Mark G for GC. */
static void
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 0f3119f19ba..412fd318dd7 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -753,6 +753,9 @@ place_field (rli, field)
rli->offset = round_up (rli->offset, desired_align / BITS_PER_UNIT);
}
+ if (! TREE_CONSTANT (rli->offset))
+ rli->offset_align = desired_align;
+
}
/* Handle compatibility with PCC. Note that if the record has any
@@ -821,9 +824,6 @@ place_field (rli, field)
}
#endif
- if (! TREE_CONSTANT (rli->offset))
- rli->offset_align = DECL_ALIGN (field);
-
/* Offset so far becomes the position of this field after normalizing. */
normalize_rli (rli);
DECL_FIELD_OFFSET (field) = rli->offset;
@@ -866,6 +866,7 @@ place_field (rli, field)
rli->offset
= size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
rli->bitpos = bitsize_zero_node;
+ rli->offset_align = MIN (rli->offset_align, DECL_ALIGN (field));
}
else
{
diff --git a/gcc/system.h b/gcc/system.h
index cdbcf9d62c1..0d1da2cd3f2 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -547,4 +547,24 @@ extern void abort PARAMS ((void));
/* Get libiberty declarations. */
#include "libiberty.h"
+/* Make sure that ONLY_INT_FIELDS has an integral value. */
+#ifdef ONLY_INT_FIELDS
+#undef ONLY_INT_FIELDS
+#define ONLY_INT_FIELDS 1
+#else
+#define ONLY_INT_FIELDS 0
+#endif
+
+/* Enumerated bitfields are safe to use unless we've been explictly told
+ * otherwise or if they are signed. */
+
+#define USE_ENUM_BITFIELDS (__GNUC__ || (!ONLY_INT_FIELDS && ENUM_BITFIELDS_ARE_UNSIGNED))
+
+#if USE_ENUM_BITFIELDS
+#define ENUM_BITFIELD(TYPE) enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
+
#endif /* __GCC_SYSTEM_H__ */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a3dd9f9add3..c5c35f81e5d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,16 @@
+Thu Apr 20 11:57:03 2000 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.dg/20000420-1.c: New test.
+
+2000-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * g++.abi/ptrflags.C: New test.
+ * g++.eh/catchptr1.C: Test incomplete pointer chains.
+
+2000-04-19 Zack Weinberg <zack@wolery.cumb.org>
+
+ * gcc.dg/20000419-1.c: New test.
+
Wed Apr 12 10:25:08 2000 Jeffrey A Law (law@cygnus.com)
* gcc.c-torture/execute/20000412-5.c: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C
index 5d8cf9d0197..8c4c93eb667 100644
--- a/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C
+++ b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C
@@ -108,10 +108,10 @@ void S4::s1 ()
S2-in-S4 secondary vtable
- S4::s1 vcall offset
S1 vbase offset
- S2:s0 vcall offset
+ S4::s1 vcall offset
S0 vbase offset
+ S2:s0 vcall offset
S2 offset to top
S4 RTTI
S2::s0
@@ -151,10 +151,12 @@ int main ()
return 5;
if (*vtbl++ != (ptrdiff_t) &s1__2S4)
return 6;
- // All the vcall and vbase offsets should be zero.
+ // The S1 vbase offset.
if (*vtbl++ != 0)
return 7;
- if (*vtbl++ != 0)
+ // The S4::s1 vcall offset is negative; once you convert to S2, you
+ // have to convert to S4 to find the final overrider.
+ if (*vtbl++ != ((char*) &s4 - (char*) (S2*) &s4))
return 8;
if (*vtbl++ != 0)
return 9;
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/catchptr1.C b/gcc/testsuite/g++.old-deja/g++.eh/catchptr1.C
index 3c74b8d3496..c88b36aa12b 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/catchptr1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/catchptr1.C
@@ -27,6 +27,7 @@ int test0 ()
{
return 0;
}
+ return -1;
}
int test1 ()
@@ -44,6 +45,7 @@ int test1 ()
{
return 0;
}
+ return -1;
}
int test2 ()
@@ -61,6 +63,7 @@ int test2 ()
{
return 1;
}
+ return -1;
}
int test3 ()
@@ -78,6 +81,7 @@ int test3 ()
{
return 1;
}
+ return -1;
}
int test4 ()
@@ -100,6 +104,7 @@ int test4 ()
{
return 2;
}
+ return -1;
}
int test5 ()
@@ -116,6 +121,7 @@ int test5 ()
{
return 1;
}
+ return -1;
}
int test6 ()
@@ -148,6 +154,7 @@ int test6 ()
{
return 1;
}
+ return -1;
}
int test7 ()
@@ -172,11 +179,13 @@ int test7 ()
{
return 3;
}
+ return -1;
}
-#if 0
int test8 ()
{
+#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
+// old-abi fails this test, by segfaulting in the runtime.
try
{
throw (B **)0;
@@ -193,8 +202,35 @@ int test8 ()
{
return 2;
}
+ return -1;
+#endif
+ return 0;
}
+
+int test9 ()
+{
+#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
+// old-abi fails this test, by segfaulting in the runtime.
+ try
+ {
+ throw (B **)0;
+ }
+ catch (C const *const *)
+ {
+ return 1;
+ }
+ catch (B const *const *)
+ {
+ return 0;
+ }
+ catch (...)
+ {
+ return 2;
+ }
+ return -1;
#endif
+ return 0;
+}
static int (*tests[])() =
{
@@ -208,9 +244,8 @@ static int (*tests[])() =
test6,
test7,
-#if 0
test8,
-#endif
+ test9,
NULL
};
diff --git a/gcc/testsuite/g++.old-deja/g++.oliva/ChangeLog b/gcc/testsuite/g++.old-deja/g++.oliva/ChangeLog
index 2d71605da55..b6e486f5a17 100644
--- a/gcc/testsuite/g++.old-deja/g++.oliva/ChangeLog
+++ b/gcc/testsuite/g++.old-deja/g++.oliva/ChangeLog
@@ -1,3 +1,7 @@
+2000-04-19 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * stkalign.C: New test.
+
1999-12-22 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
* nameret2.C: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb127.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb127.C
index cf5f69fc1a6..655aca9bc86 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb127.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb127.C
@@ -46,7 +46,7 @@ void ODEsolver::init()
void ODEsolver::timeloop(vector<double>& y, double ts, double te, double dt)
{
- (ODEsolver::useMethod)(y,ts,dt);
+ (ODEsolver::useMethod)(y,ts,dt); // ERROR - should use this->*
}
int main (int nargs, char** args)
diff --git a/gcc/testsuite/gcc.c-torture/ChangeLog b/gcc/testsuite/gcc.c-torture/ChangeLog
index 38acdbd27ec..ec4f7194c33 100644
--- a/gcc/testsuite/gcc.c-torture/ChangeLog
+++ b/gcc/testsuite/gcc.c-torture/ChangeLog
@@ -1,3 +1,12 @@
+Wed Apr 19 09:16:32 2000 Catherine Moore <clm@cygnus.com>
+
+ * execute/921017-1.c: Check for NO_TRAMPOLINES.
+
+2000-04-19 Greg McGary <gkm@gnu.org>
+
+ * execute/20000419-1.c: New test for arg clobbering with
+ sibling-call optimizations.
+
Wed Apr 12 22:54:02 2000 Hans-Peter Nilsson <hp@axis.com>
* execute/20000412-6.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/921017-1.c b/gcc/testsuite/gcc.c-torture/execute/921017-1.c
index 3a0db5c4d56..ab68fc08498 100644
--- a/gcc/testsuite/gcc.c-torture/execute/921017-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/921017-1.c
@@ -10,6 +10,8 @@ f(n)
}
main()
{
+#ifndef NO_TRAMPOLINES
if(f(2)!=4711)abort();
+#endif
exit(0);
}
diff --git a/gcc/testsuite/gcc.dg/cpp-mi.c b/gcc/testsuite/gcc.dg/cpp-mi.c
index 1fb62788925..a05b279558b 100644
--- a/gcc/testsuite/gcc.dg/cpp-mi.c
+++ b/gcc/testsuite/gcc.dg/cpp-mi.c
@@ -1,10 +1,6 @@
/* Test "ignore redundant include" facility.
- This doesn't test for the case where the file is opened, and then ignored
- (the file shouldn't have even been opened). That would require tracing
- system calls. It could be done on some systems however. */
-
-/* We have to test two cases: C comments at the top and C++ comments
- at the top. */
+ We must test with C and C++ comments outside the guard conditional;
+ also, we test guarding with #ifndef and #if !defined. */
/* { dg-do preprocess }
{ dg-options "" } */
@@ -15,16 +11,24 @@
#include "cpp-micc.h"
#include "cpp-micc.h"
-main ()
+#include "cpp-mind.h"
+#include "cpp-mind.h"
+
+#include "cpp-mindp.h"
+#include "cpp-mindp.h"
+
+int
+main (void)
{
+ return a + b + c + d;
}
/*
{ dg-final { if ![file exists cpp-mi.i] { return } } }
- { dg-final { set tmp [grep cpp-mi.i cpp-micc? line] } }
+ { dg-final { set tmp [grep cpp-mi.i {cpp-mi.*\.h} line] } }
{ dg-final { # send_user "$tmp\n" } }
- { dg-final { if [regexp "^{\[0-9\]+ cpp-mic} {\[0-9\]+ cpp-micc}$" $tmp] \{ } }
+ { dg-final { if [regexp "^{\[0-9\]+ cpp-mic\.h} {\[0-9\]+ cpp-micc\.h} {\[0-9\]+ cpp-mind\.h} {\[0-9\]+ cpp-mindp\.h}$" $tmp] \{ } }
{ dg-final { pass "cpp-mi.c: redundant include check" } }
{ dg-final { \} else \{ } }
{ dg-final { fail "cpp-mi.c: redundant include check" } }
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e7e93fde7c9..e85ff9d7bc5 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -251,6 +251,7 @@ struct dump_file_info
enum dump_file_index
{
DFI_rtl,
+ DFI_sibling,
DFI_jump,
DFI_cse,
DFI_addressof,
@@ -285,6 +286,7 @@ enum dump_file_index
struct dump_file_info dump_file[DFI_MAX] =
{
{ "rtl", 'r', 0, 0, 0 },
+ { "sibling", 'i', 0, 0, 0 },
{ "jump", 'j', 0, 0, 0 },
{ "cse", 's', 0, 0, 0 },
{ "addressof", 'F', 0, 0, 0 },
@@ -2895,11 +2897,17 @@ rest_of_compilation (decl)
goto exit_rest_of_compilation;
}
+ init_EXPR_INSN_LIST_cache ();
+
/* We may have potential sibling or tail recursion sites. Select one
(of possibly multiple) methods of performing the call. */
- init_EXPR_INSN_LIST_cache ();
- if (flag_optimize_sibling_calls)
- optimize_sibling_and_tail_recursive_calls ();
+ open_dump_file (DFI_sibling, decl);
+ TIMEVAR (jump_time,
+ {
+ if (flag_optimize_sibling_calls)
+ optimize_sibling_and_tail_recursive_calls ();
+ });
+ close_dump_file (DFI_sibling, print_rtl, get_insns ());
if (ggc_p)
ggc_collect ();
@@ -2964,6 +2972,10 @@ rest_of_compilation (decl)
of the function. */
TIMEVAR (jump_time,
{
+ /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this
+ before jump optimization switches branch directions. */
+ expected_value_to_br_prob ();
+
reg_scan (insns, max_reg_num (), 0);
jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
JUMP_AFTER_REGSCAN);
diff --git a/gcc/tree.c b/gcc/tree.c
index 72d670cf3ac..7a04d49953a 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3400,11 +3400,8 @@ build1 (code, type, node)
TREE_SET_PERMANENT (t);
TREE_OPERAND (t, 0) = node;
- if (node && first_rtl_op (code) != 0)
- {
- if (TREE_SIDE_EFFECTS (node))
- TREE_SIDE_EFFECTS (t) = 1;
- }
+ if (node && first_rtl_op (code) != 0 && TREE_SIDE_EFFECTS (node))
+ TREE_SIDE_EFFECTS (t) = 1;
switch (code)
{
@@ -4082,8 +4079,8 @@ type_hash_add (hashcode, type)
h = (struct type_hash *) permalloc (sizeof (struct type_hash));
h->hash = hashcode;
h->type = type;
- loc = htab_find_slot_with_hash (type_hash_table, h, hashcode, 1);
- *(struct type_hash**)loc = h;
+ loc = htab_find_slot_with_hash (type_hash_table, h, hashcode, INSERT);
+ *(struct type_hash**) loc = h;
}
/* Given TYPE, and HASHCODE its hash code, return the canonical
diff --git a/gcc/tree.h b/gcc/tree.h
index 2aa0f88d3cf..ae194cd43d5 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -119,22 +119,14 @@ typedef union tree_node *tree;
/* Every kind of tree node starts with this structure,
so all nodes have these fields.
- See the accessor macros, defined below, for documentation of the fields.
-
- DO NOT change the layout of tree_common unless absolutely necessary. Some
- front-ends (namely g++) depend on the internal layout of this tructure.
- See my_tree_cons in the cp subdir for such uglyness. Ugh. */
+ See the accessor macros, defined below, for documentation of the
+ fields. */
struct tree_common
{
union tree_node *chain;
union tree_node *type;
-#ifdef ONLY_INT_FIELDS
- unsigned int code : 8;
-#else
- enum tree_code code : 8;
-#endif
-
+ ENUM_BITFIELD(tree_code) code : 8;
unsigned side_effects_flag : 1;
unsigned constant_flag : 1;
unsigned permanent_flag : 1;
@@ -909,11 +901,7 @@ struct tree_type
unsigned int uid;
unsigned int precision : 9;
-#ifdef ONLY_INT_FIELDS
- unsigned int mode : 7;
-#else
- enum machine_mode mode : 7;
-#endif
+ ENUM_BITFIELD(machine_mode) mode : 7;
unsigned string_flag : 1;
unsigned no_force_blk_flag : 1;
@@ -1112,7 +1100,7 @@ struct tree_type
#define DECL_SIZE_UNIT(NODE) (DECL_CHECK (NODE)->decl.size_unit)
/* Holds the alignment required for the datum. */
#define DECL_ALIGN(NODE) (DECL_CHECK (NODE)->decl.u1.a.align)
-/* For FIELD_DECLs, holds the alignment that DECL_FEILD_OFFSET has. */
+/* For FIELD_DECLs, holds the alignment that DECL_FIELD_OFFSET has. */
#define DECL_OFFSET_ALIGN(NODE) (FIELD_DECL_CHECK (NODE)->decl.u1.a.off_align)
/* Holds the machine mode corresponding to the declaration of a variable or
field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
@@ -1397,11 +1385,7 @@ struct tree_decl
unsigned malloc_flag : 1;
unsigned no_limit_stack : 1;
unsigned pure_flag : 1;
-#ifdef ONLY_INT_FIELDS
- unsigned int built_in_class : 2;
-#else
- enum built_in_class built_in_class : 2;
-#endif
+ ENUM_BITFIELD(built_in_class) built_in_class : 2;
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
diff --git a/gcc/version.c b/gcc/version.c
index da0bdeedc99..763502a1796 100644
--- a/gcc/version.c
+++ b/gcc/version.c
@@ -1,4 +1,4 @@
#include "gansidecl.h"
#include "version.h"
-const char *const version_string = "2.96 20000415 (experimental)";
+const char *const version_string = "2.96 20000420 (experimental)";
diff --git a/include/ChangeLog b/include/ChangeLog
index e2bf4c15cbe..06c2894bb0f 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,13 @@
+Tue Apr 18 16:22:30 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * hashtab.h (enum insert_option): New type.
+ (htab_find_slot, htab_find_slot_with_hash): Use it.
+
+2000-04-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * symcat.h: Honor autoconf macro HAVE_STRINGIZE. Add
+ comments/caveats with regard to traditional C behavior.
+
2000-04-05 Richard Henderson <rth@cygnus.com>
* splay-tree.h (splay_tree_remove): Declare.
diff --git a/include/hashtab.h b/include/hashtab.h
index 2426708e378..a516c45f52d 100644
--- a/include/hashtab.h
+++ b/include/hashtab.h
@@ -102,6 +102,9 @@ struct htab
typedef struct htab *htab_t;
+/* An enum saying whether we insert into the hash table or not. */
+enum insert_option {NO_INSERT, INSERT};
+
/* The prototypes of the package functions. */
extern htab_t htab_create PARAMS ((size_t, htab_hash,
@@ -110,11 +113,13 @@ extern void htab_delete PARAMS ((htab_t));
extern void htab_empty PARAMS ((htab_t));
extern void *htab_find PARAMS ((htab_t, const void *));
-extern void **htab_find_slot PARAMS ((htab_t, const void *, int));
-extern void *htab_find_with_hash PARAMS ((htab_t, const void *,
- hashval_t));
-extern void **htab_find_slot_with_hash PARAMS ((htab_t, const void *,
- hashval_t, int));
+extern void **htab_find_slot PARAMS ((htab_t, const void *,
+ enum insert_option));
+extern void *htab_find_with_hash PARAMS ((htab_t, const void *,
+ hashval_t));
+extern void **htab_find_slot_with_hash PARAMS ((htab_t, const void *,
+ hashval_t,
+ enum insert_option));
extern void htab_clear_slot PARAMS ((htab_t, void **));
extern void htab_remove_elt PARAMS ((htab_t, void *));
diff --git a/include/symcat.h b/include/symcat.h
index 3e27162b264..41589d42add 100644
--- a/include/symcat.h
+++ b/include/symcat.h
@@ -19,12 +19,16 @@
#ifndef SYM_CAT_H
#define SYM_CAT_H
-#if defined (__STDC__) || defined (ALMOST_STDC)
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
#define CONCAT2(a,b) a##b
#define CONCAT3(a,b,c) a##b##c
#define CONCAT4(a,b,c,d) a##b##c##d
#define STRINGX(s) #s
#else
+/* Note one should never pass extra whitespace to the CONCATn macros,
+ e.g. CONCAT2(foo, bar) because traditonal C will keep the space between
+ the two labels instead of concatenating them. Instead, make sure to
+ write CONCAT2(foo,bar). */
#define CONCAT2(a,b) a/**/b
#define CONCAT3(a,b,c) a/**/b/**/c
#define CONCAT4(a,b,c,d) a/**/b/**/c/**/d
@@ -35,6 +39,11 @@
#define XCONCAT3(a,b,c) CONCAT3(a,b,c)
#define XCONCAT4(a,b,c,d) CONCAT4(a,b,c,d)
+/* Note the layer of indirection here is typically used to allow
+ stringification of the expansion of macros. I.e. "#define foo
+ bar", "XSTRING(foo)", to yield "bar". Be aware that this only
+ works for __STDC__, not for traditional C which will still resolve
+ to "foo". */
#define XSTRING(s) STRINGX(s)
#endif SYM_CAT_H
diff --git a/libf2c/libF77/Version.c b/libf2c/libF77/Version.c
index 5bd2176b938..4894231a0ce 100644
--- a/libf2c/libF77/Version.c
+++ b/libf2c/libF77/Version.c
@@ -3,7 +3,7 @@ static char junk[] = "\n@(#)LIBF77 VERSION 19991115\n";
/*
*/
-char __G77_LIBF77_VERSION__[] = "0.5.25 20000415 (prerelease)";
+char __G77_LIBF77_VERSION__[] = "0.5.25 20000420 (prerelease)";
/*
2.00 11 June 1980. File version.c added to library.
diff --git a/libf2c/libI77/Version.c b/libf2c/libI77/Version.c
index d244672e19c..be2e836228a 100644
--- a/libf2c/libI77/Version.c
+++ b/libf2c/libI77/Version.c
@@ -3,7 +3,7 @@ static char junk[] = "\n@(#) LIBI77 VERSION pjw,dmg-mods 19991115\n";
/*
*/
-char __G77_LIBI77_VERSION__[] = "0.5.25 20000415 (prerelease)";
+char __G77_LIBI77_VERSION__[] = "0.5.25 20000420 (prerelease)";
/*
2.01 $ format added
diff --git a/libf2c/libU77/Version.c b/libf2c/libU77/Version.c
index 699e15edeab..25353aacb21 100644
--- a/libf2c/libU77/Version.c
+++ b/libf2c/libU77/Version.c
@@ -1,6 +1,6 @@
static char junk[] = "\n@(#) LIBU77 VERSION 19980709\n";
-char __G77_LIBU77_VERSION__[] = "0.5.25 20000415 (prerelease)";
+char __G77_LIBU77_VERSION__[] = "0.5.25 20000420 (prerelease)";
#include <stdio.h>
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index d78a86a3585..238e877b9bf 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,13 @@
+Tue Apr 18 16:23:31 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * hashtab.c: Various minor cleanups.
+ (htab_find_slot_with_hash): INSERT is now enum insert_option.
+ (htab_find_slot): Likewise.
+
+2000-04-16 Dave Pitts <dpitts@cozx.com>
+
+ * cplus-dem.c (cplus_demangle_opname): Changed to use islower.
+
2000-04-05 Richard Henderson <rth@cygnus.com>
* splay-tree.c (splay_tree_remove): New.
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 52249d2b580..0c49c55ff6e 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -636,8 +636,8 @@ cplus_demangle_opname (opname, result, options)
}
}
else if (opname[0] == '_' && opname[1] == '_'
- && opname[2] >= 'a' && opname[2] <= 'z'
- && opname[3] >= 'a' && opname[3] <= 'z')
+ && islower(opname[2])
+ && islower(opname[3]))
{
if (opname[4] == '\0')
{
@@ -4188,8 +4188,8 @@ demangle_function_name (work, mangled, declp, scan)
}
}
else if (declp->b[0] == '_' && declp->b[1] == '_'
- && declp->b[2] >= 'a' && declp->b[2] <= 'z'
- && declp->b[3] >= 'a' && declp->b[3] <= 'z')
+ && islower(declp->b[2])
+ && islower(declp->b[3]))
{
if (declp->b[4] == '\0')
{
diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c
index ba897b2b03d..2d1c09d9522 100644
--- a/libiberty/hashtab.c
+++ b/libiberty/hashtab.c
@@ -58,7 +58,7 @@ Boston, MA 02111-1307, USA. */
static unsigned long higher_prime_number PARAMS ((unsigned long));
/* The following function returns the nearest prime number which is
- greater than a given source number. */
+ greater than a given source number, N. */
static unsigned long
higher_prime_number (n)
@@ -66,20 +66,24 @@ higher_prime_number (n)
{
unsigned long i;
- n |= 0x01; /* Force N to be odd. */
+ /* Ensure we have a larger number and then force to odd. */
+ n++;
+ n |= 0x01;
+
+ /* All odd numbers < 9 are prime. */
if (n < 9)
- return n; /* All odd numbers < 9 are prime. */
+ return n;
+
+ /* Otherwise find the next prime using a sieve. */
next:
- n += 2;
- i = 3;
- do
- {
- if (n % i == 0)
- goto next;
- i += 2;
- }
- while ((i * i) <= n);
+
+ for (i = 3; i * i <= n; i += 2)
+ if (n % i == 0)
+ {
+ n += 2;
+ goto next;
+ }
return n;
}
@@ -116,13 +120,12 @@ htab_delete (htab)
htab_t htab;
{
int i;
+
if (htab->del_f)
for (i = htab->size - 1; i >= 0; i--)
- {
- if (htab->entries[i] != EMPTY_ENTRY
- && htab->entries[i] != DELETED_ENTRY)
- (*htab->del_f) (htab->entries[i]);
- }
+ if (htab->entries[i] != EMPTY_ENTRY
+ && htab->entries[i] != DELETED_ENTRY)
+ (*htab->del_f) (htab->entries[i]);
free (htab->entries);
free (htab);
@@ -135,13 +138,12 @@ htab_empty (htab)
htab_t htab;
{
int i;
+
if (htab->del_f)
for (i = htab->size - 1; i >= 0; i--)
- {
- if (htab->entries[i] != EMPTY_ENTRY
- && htab->entries[i] != DELETED_ENTRY)
- (*htab->del_f) (htab->entries[i]);
- }
+ if (htab->entries[i] != EMPTY_ENTRY
+ && htab->entries[i] != DELETED_ENTRY)
+ (*htab->del_f) (htab->entries[i]);
memset (htab->entries, 0, htab->size * sizeof (void *));
}
@@ -152,6 +154,7 @@ htab_empty (htab)
hash table.
This function also assumes there are no deleted entries in the table.
HASH is the hash value for the element to be inserted. */
+
static void **
find_empty_slot_for_expand (htab, hash)
htab_t htab;
@@ -164,10 +167,10 @@ find_empty_slot_for_expand (htab, hash)
for (;;)
{
void **slot = htab->entries + index;
+
if (*slot == EMPTY_ENTRY)
return slot;
-
- if (*slot == DELETED_ENTRY)
+ else if (*slot == DELETED_ENTRY)
abort ();
index += hash2;
@@ -203,14 +206,18 @@ htab_expand (htab)
do
{
void *x = *p;
+
if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
{
void **q = find_empty_slot_for_expand (htab, (*htab->hash_f) (x));
+
*q = x;
}
+
p++;
}
while (p < olimit);
+
free (oentries);
}
@@ -255,6 +262,7 @@ htab_find_with_hash (htab, element, hash)
/* Like htab_find_slot_with_hash, but compute the hash value from the
element. */
+
void *
htab_find (htab, element)
htab_t htab;
@@ -274,14 +282,14 @@ htab_find_slot_with_hash (htab, element, hash, insert)
htab_t htab;
const void *element;
hashval_t hash;
- int insert;
+ enum insert_option insert;
{
void **first_deleted_slot;
unsigned int index;
hashval_t hash2;
size_t size;
- if (insert && htab->size * 3 <= htab->n_elements * 4)
+ if (insert == INSERT && htab->size * 3 <= htab->n_elements * 4)
htab_expand (htab);
size = htab->size;
@@ -296,7 +304,7 @@ htab_find_slot_with_hash (htab, element, hash, insert)
void *entry = htab->entries[index];
if (entry == EMPTY_ENTRY)
{
- if (!insert)
+ if (insert == NO_INSERT)
return NULL;
htab->n_elements++;
@@ -315,11 +323,8 @@ htab_find_slot_with_hash (htab, element, hash, insert)
if (!first_deleted_slot)
first_deleted_slot = &htab->entries[index];
}
- else
- {
- if ((*htab->eq_f) (entry, element))
- return &htab->entries[index];
- }
+ else if ((*htab->eq_f) (entry, element))
+ return &htab->entries[index];
htab->collisions++;
index += hash2;
@@ -330,11 +335,12 @@ htab_find_slot_with_hash (htab, element, hash, insert)
/* Like htab_find_slot_with_hash, but compute the hash value from the
element. */
+
void **
htab_find_slot (htab, element, insert)
htab_t htab;
const void *element;
- int insert;
+ enum insert_option insert;
{
return htab_find_slot_with_hash (htab, element, (*htab->hash_f) (element),
insert);
@@ -351,7 +357,7 @@ htab_remove_elt (htab, element)
{
void **slot;
- slot = htab_find_slot (htab, element, 0);
+ slot = htab_find_slot (htab, element, NO_INSERT);
if (*slot == EMPTY_ENTRY)
return;
@@ -374,8 +380,10 @@ htab_clear_slot (htab, slot)
if (slot < htab->entries || slot >= htab->entries + htab->size
|| *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY)
abort ();
+
if (htab->del_f)
(*htab->del_f) (*slot);
+
*slot = DELETED_ENTRY;
htab->n_deleted++;
}
@@ -391,12 +399,13 @@ htab_traverse (htab, callback, info)
htab_trav callback;
void *info;
{
- void **slot, **limit;
- slot = htab->entries;
- limit = slot + htab->size;
+ void **slot = htab->entries;
+ void **limit = slot + htab->size;
+
do
{
void *x = *slot;
+
if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
if (!(*callback) (slot, info))
break;
@@ -404,7 +413,7 @@ htab_traverse (htab, callback, info)
while (++slot < limit);
}
-/* The following function returns current size of given hash table. */
+/* Return the current size of given hash table. */
size_t
htab_size (htab)
@@ -413,8 +422,7 @@ htab_size (htab)
return htab->size;
}
-/* The following function returns current number of elements in given
- hash table. */
+/* Return the current number of elements in given hash table. */
size_t
htab_elements (htab)
@@ -423,17 +431,15 @@ htab_elements (htab)
return htab->n_elements - htab->n_deleted;
}
-/* The following function returns number of percents of fixed
- collisions during all work with given hash table. */
+/* Return the fraction of fixed collisions during all work with given
+ hash table. */
double
htab_collisions (htab)
htab_t htab;
{
- int searches;
-
- searches = htab->searches;
- if (searches == 0)
+ if (htab->searches == 0)
return 0.0;
- return (double)htab->collisions / (double)searches;
+
+ return (double) htab->collisions / (double) htab->searches;
}